cancel
Showing results for 
Search instead for 
Did you mean: 

Any body encountered " cannot unregister the given destination configuration " error for SAP.Net 3.0 connector

Former Member
0 Kudos
1,329

I have a requirement where I need to call call SAP frequently and get the data.

For this I am registering, getting the data  and unregistering the destination. But some times I am receiving error message which says "cannot unregister the given destination configuration"

Does any body knows how to resolve this.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Markus,

Thanks for the reply. I never mentioned that the NSAPConnector approach is the correct approach.

As a developer I do not have control over the infrastructure. So its needed to mold code to fit the existing infrastructure. I am migrating the code from SAP Connector 2.0 to 3.0. So do not have many option available with me. Your reply make sense though.

Do you have some documentation where it has been mentioned or a place where you have discussed it. I might have missed those, would be great if you can share the links.

Regards,

Anand

hynek_petrak
Active Participant
0 Kudos

HI Anand,

did you try to register your destination configuration in the Application_Start method in Global.asax? This suppose to be executed once per the lifetime of an application in the asp.net. This's been working for me so far.

hynek


public class Global : HttpApplication {

        void Application_Start(object sender, EventArgs e) {

            // Code that runs on application startup

            RouteConfig.RegisterRoutes(RouteTable.Routes);

            IDestinationConfiguration dc = new SqlDestinationConfiguration();

            RfcDestinationManager.RegisterDestinationConfiguration(dc);

        }

        void Application_End(object sender, EventArgs e) {

            //  Code that runs on application shutdown

        }

        void Application_Error(object sender, EventArgs e) {

            // Code that runs when an unhandled error occurs

        }

    }

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Anand,

so far it is mentioned not in that detail in the documentation, but pretty short. I can recommend to have a look at the API documentation of NCo and the programming guide. In addition it makes sense not only to look at NCo, but also at JCo API documentation. Both JCo 3.0 and NCo 3.0 share the same concepts in that regard. This is also a general remak - many concepts are the same. So, in case you don't find an answer for one of your questions about NCo, check whether there is an answer for JCo.

Best regards,

Markus

Former Member
0 Kudos

On ASP.NET MVC (as I know)  is a bad practice to use the Application_Start because can be executed more than one time , maybe can be more effective is you used something like Singleton pattern (static variable flag to ensure the first tie execution of the method)

former_member197445
Contributor
0 Kudos

I respectfully disagree.  Nothing wrong with using Application_Start.  This event only fires when the IIS app pool comes on-line.

Former Member
0 Kudos

Thanks Ahr,  I overreacted my answer haha I was thinking in the context that there are more than one application instance in the same project (IIS works like you said but can be more than one instance after that) but  re-thinking  about that, the Application start method, in theory, will be run only one time.

There is still the small  possibility  only when there is more instance of the application class at the same time.

Is a best practice use Application start but is another best practice never assume that the thinks will work perfectly without testing it and know some of the behavior.

Regards,
Eduardo

Answers (4)

Answers (4)

Former Member
0 Kudos

Hi Markus and Hynek,

Thanks for your replies. It gave more clarity to the SAP Component. I have used the Global.asax, and it seems to be working fine. Not seeing any errors.

Registering the destination in Application_Start is the correct way. Have seen lots of articles over the web where people are registering, doing the processing and unregistered it, which is not needed.

Thanks guys for the help, truly appreciate your prompt answers.

Best Regards,

Anand

Former Member
0 Kudos

Hi Markus

The SAP connector is included in a Webservice. This Webservice is being called by my web application. So every time I am calling the webservice I need to create an instance of the SAP connector to connect to SAP. Although I am taking care to register the destination absolutely when necessary using these lines

if (RfcDestinationManager.TryGetDestination(_destinationConfigName) == null)

                    {

                        RfcDestinationManager.RegisterDestinationConfiguration(_destinationConfiguration);

                    }

, but still I encounter this issue some time.

If I do not unregister it I always get this error when I again comeback to call SAP

"Destination configuration already initialized"

So lots of people over internet has suggested the unregister option.

Also there is a wrapper available for SAP Connector, which also does the similar things that I have done for Registering and unregistering.

NSAPConnector - Home

Regards,

Anand

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Anand,

only because NSAPConnector does use the same approach, doesn't make it correct. Please note: a destination is not a connection and an IDestinationConfiguration is not a destination, but an implementation of a destination data provider that stores many destinations. Checking for a certain destination and then noticing that it's not there and concluding from this fact that you need to register an implementation of IDestinationConfiguration is simply not correct.

You need to separate the application code from the infrastructure parts. There should be a separate deployment of some IDestinationConfiguration - not necessarily yours. Such an approach is not the one you should choose. An application should always assume that there is a valid IDestinationConfiguration. If the destination is not there, which is required by the application, this should be considered as an unrecoverable situation for the application - an administrator should have configured it at the right, central place. The implementation of the IDestinationConfiguration should be deployed separately - yours or some other one. And this should happen before some application coding is executed.

Best regards,

Markus

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Anand,

Hynek's question is a pretty relevant one. Only in rare cases it should be required to remove the implementation of IDestinationConfiguration again. Please note that an IDestinationConfiguration is supposed to encapsulate the storage of all destinations needed within an application -  it's not only for a single destination.

One remark though: Removing a configuration fails, whenever you try to remove one that is not the instance that you registered before. It's a true instance equality needed not a object equality.

Best regards,

Markus

Former Member
0 Kudos

Hi , I have the same problem.

I see that you mention something interesting -


... Please note that an IDestinationConfiguration is supposed to encapsulate the storage of all destinations needed within an application -  it's not only for a single destination.

How can I do that?

I tried the next:

1) Register my configuration normally and try to unregister the old and set the new (there are different servers and Sys IDs, customsDestination will not work  as I know )     but fails on the unregister part.

2) Based on your comment all the destinations needs to be in one object  that implements IDestinationConfiguration, so I tried to register all in one but fails in new requests

  

IDestinationConfiguration implementation


/// <summary>

        ///

        /// </summary>

        /// <param name="destinationsContainer">app config key with  comma separated values</param>

        /// <returns></returns>

        public RfcConfigParameters GetParameters (string destinationsContainer)

        {

            var destinations = ConfigurationManager.AppSettings[destinationsContainer].Split(',');

            if (this.destinationListparams == null)

                this.destinationListparams = new List<RfcConfigParameters>();

            RfcConfigParameters lastParms = new RfcConfigParameters();

            foreach (var destinationNamePF in destinations)

            {

                RfcConfigParameters parms = new RfcConfigParameters();

                parms.Add(RfcConfigParameters.Name, ConfigurationManager.AppSettings[destinationNamePF + "_NAME"]);

                parms.Add(RfcConfigParameters.AppServerHost, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_APPSERVERHOST"]);

                parms.Add(RfcConfigParameters.SystemNumber, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_SYSTEMNUM"]);

                parms.Add(RfcConfigParameters.SystemID, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_DES_SYS_ID"]);

                parms.Add(RfcConfigParameters.User, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_USERNAME"]);

                parms.Add(RfcConfigParameters.Password, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_PASSWORD"]);

                parms.Add(RfcConfigParameters.Client, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_CLIENT"]);

                parms.Add(RfcConfigParameters.Language, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_LANGUAGE"]);

                parms.Add(RfcConfigParameters.PoolSize, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_POOLSIZE"]);

                parms.Add(RfcConfigParameters.IdleTimeout, ConfigurationManager.AppSettings[destinationNamePF + "_SAP_IDLE_TIMEOUT"]);

                lastParms = parms;

                this.destinationListparams.Add(parms);

            }

            return lastParms;

        }

Registering the object calling the method


public static void ApplicationStart()

        {

            if(destinationIsInitialized)return;

            destinationIsInitialized = true;

        

            IDestinationConfiguration destinationConfig = null;

          

            destinationConfig = new SAPDestinationConfig();

            destinationConfig.GetParameters("SAP_CONN_ALLIASES");

            //Get the first destination an check it out

            string destinationConfigName= ConfigurationManager.AppSettings["SAP_CONN_ALLIASES"].Split(',')[0];

         

           

                   

            if (RfcDestinationManager.TryGetDestination(destinationConfigName) == null)

            {

                RfcDestinationManager.RegisterDestinationConfiguration(destinationConfig);

                destinationIsInitialized = true;

                currentDestination = destinationConfigName;   

            }

           

        }


How can I register all my destinations at once in the same object as you mention?


I'm really stuck with this any help is appreciate

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Eduardo,

you should never register a IDestinationConfiguration only because a certain destination is not available in the current storage. You can check whether there is already one registered using RfcDestinationManager.IsDestinationConfigurationRegistered() and if not registering will work fine. But typically, there is only one implementation deployed to an application environment. In this implementation, GetParameters(name) should check whether there is a destination available in the storage with that name and return the parameters for it. Otherwise it signals with null that such a destination does not exist. The storage will have manipulation APIs that will allow to add new destinations or remove ones that are no longer needed. Hopefully, it is also bound to a UI so that an administrator can manage such configurations nicely. Thus all destinations are available via the RfcDetsinationManager that are managed by the storage.

The IDestinationConfiguration related code should be separated from the actual application code and the application code should actually not care which implementation is used, but simply use the RfcDestination, which is making use of the configuration.

Best regards,

Markus

Former Member
0 Kudos

Thanks

I research by myself the configuration, after some errors with the XML config file
I got this .


I used the config file to add  destination connections and in C# code you never need to register them  (why the documentation don't say that? .. well in some way It says it) and just  call the destinations in c# code.


This is How you can add multiple destinations in SAP .net connector 3.

Is a better practice to use the config this is a template



<configSections>

    <sectionGroup name="SAP.Middleware.Connector">

      <section name="GeneralSettings" type="SAP.Middleware.Connector.RfcGeneralConfiguration,sapnco" />

  

      <sectionGroup name="ClientSettings">

        <section name="DestinationConfiguration" type="SAP.Middleware.Connector.RfcDestinationConfiguration,sapnco" />

      </sectionGroup>

    </sectionGroup>

  </configSections>

<SAP.Middleware.Connector>

  <GeneralSettings defaultTraceLevel="1" traceDir="C:\Temp" traceEncoding="UTF-8" traceType="PROCESS" />

  <ClientSettings>

    <DestinationConfiguration>

      <destinations>

        <add

            NAME="TEST_INST_1"    USER="MYUSER"

            PASSWD="SECRET_PASS" SYSID="INST_1"

            CLIENT="300"      ASHOST="sapinst_1.sapnet.company.com"

            SYSNR="00"        LANG="EN"

            POOL_SIZE="15"    MAX_POOL_SIZE="25"

            IDLE_TIMEOUT="60"

        />

        <add

            NAME="TEST_INST_2"    USER="MYUSER"

            PASSWD="SECRET_PASS" SYSID="INST_2"

            CLIENT="474"      ASHOST="sapinst_2.sapnet.company.com"

            SYSNR="00"        LANG="EN"

            POOL_SIZE="15"    MAX_POOL_SIZE="25"

            IDLE_TIMEOUT="60"/>

      </destinations>

    </DestinationConfiguration>

  </ClientSettings>

</SAP.Middleware.Connector>

check this out maybe is better to put his in your web service and don't register any new destinations  when you need it, instead of that you can  register all of them in config and use it later.

MarkusTolksdorf
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Eduardo,

the app.config is the default implementation for IDestinationConfiguration. In this case the destination storage is the app.config file. If that kind of destination storage is sufficient for you, ok, then you really don't have to do anything else. However, app.config might not fit all the needs in various cases, e.g. backup or security, modification via UI is cumbersome. Therefore, with a different imlpementation, the destination storage could be moved to a database and any destination added to a certain table could then be found. When registering an IDestinationConfiguration implementation, you don't register a single destination, but a storage for multiple destinations. It's actually the same like DestinationDataProvider in JCo.

Best regards,

Markus

Former Member
0 Kudos

Saved me. I needed to unregister in the case of a credentials change or a login change from SSO to non SSO during the same application running session. Maybe I did not need to follow the unregister / register approach but this is another topic.

hynek_petrak
Active Participant
0 Kudos

why do you need to unregister the destination? is that a requirement?