function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Mike LeachMike Leach 

Generating ApexService.SessionHeader

The Apex Developers Deployment guide has some psuedo code for generating an ApexService SessionHeader, but nothing specific. I've discovered that I can only generate valid SessionHeaders logging into the Org from which the WSDL was generated. Is there anything in the Apex.wsdl that binds the service to a particular Org end point, like an Enterprise WSDL does? Can Apex.wsdl be used by partners across multiple orgs? I'm guessing the ApexService.URL property perhaps needs setting? Thoughts? Suggestions? Thx
SuperfellSuperfell
You'd have to reset the destination URL to use the right instance for different orgs, other than that, it should be fine.
Mike LeachMike Leach
Here is what I'm attempting to do. Error message is "No operation available for request {http://soap.sforce.com/2006/08/apex}compileAndTest".

Any ideas?

Code:
protected ApexService m_apexBinding = null;
        public ApexService ApexServiceBinding
        {
            get
            {
                try
                {
                    if (m_apexBinding == null)
                    {
                        SforceServiceWrapper sforceBinding = new SforceServiceWrapper(true, true);

                        LoginResult lr = sforceBinding.login(userName, password);

                        if (lr == null || lr.passwordExpired)
                        {
                            string errMessage = "sForce password has expired. Could not login";
                            return null;
                        }

                        m_apexBinding = new ApexService();
                        m_apexBinding.SessionHeaderValue = new Apex.SessionHeader();
                        m_apexBinding.SessionHeaderValue.sessionId = lr.sessionId;
                        m_apexBinding.Url = lr.serverUrl;
                    }

                    return m_apexBinding;
                }
                catch (Exception ex)
                {                    
                    m_apexBinding = null;
                    return m_apexBinding;
                }
            }
        }

 


SuperfellSuperfell
The URL for the apex service is not in the loginResult as of yet. So you'll need to build it up yourself from the serverUrl in loginResult, something like

URL url = new URL(lr.serverUrl);
m_apexBinding.Url = "https://" + url.Host + "/services/Soap/s/11.1";
Mike LeachMike Leach
Thanks! That did the trick.
brad4dbrad4d
I have attempted to implement something akin to the pseudo-code suggested here and have so-far failed to get this working.  Any help would be appreciated.  
Code:
    private boolean login() throws ServiceException, MalformedURLException {
        String userName = props.getProperty("punch.service.username");
        String password = props.getProperty("punch.service.password");
        password += secCode;
        binding = (SoapBindingStub) new SforceServiceLocator().getSoap();
        binding.setTimeout(60000);
        try {
            System.out.println("LOGGING IN NOW.... \n userName = "+userName+"\n password = "+password);
            loginResult = binding.login(userName, password);
        }
        catch (LoginFault ex) {
            // The LoginFault derives from AxisFault
            ExceptionCode exCode = ex.getExceptionCode();
            if (exCode == ExceptionCode.FUNCTIONALITY_NOT_ENABLED ||
                exCode == ExceptionCode.INVALID_CLIENT ||
                exCode == ExceptionCode.INVALID_LOGIN ||
                exCode == ExceptionCode.LOGIN_DURING_RESTRICTED_DOMAIN ||
                exCode == ExceptionCode.LOGIN_DURING_RESTRICTED_TIME ||
                exCode == ExceptionCode.ORG_LOCKED ||
                exCode == ExceptionCode.PASSWORD_LOCKOUT ||
                exCode == ExceptionCode.SERVER_UNAVAILABLE ||
                exCode == ExceptionCode.TRIAL_EXPIRED ||
                exCode == ExceptionCode.UNSUPPORTED_CLIENT) {
                System.out.println("Please be sure that you have a valid username and password.");
            } else {
                // Write the fault code to the console
                System.out.println(ex.getExceptionCode());
                // Write the fault message to the console
                System.out.println("An unexpected error has occurred." + ex.getMessage());
            }
            return false;
        } catch (Exception ex) {
            System.out.println("An unexpected error has occurred: " + ex.getMessage());
            ex.printStackTrace();
            return false;
        }
        // Check if the password has expired
        if (loginResult.isPasswordExpired()) {
            System.out.println("An error has occurred. Your password has expired.");
            return false;
        }
            WakeUPServiceLocator locator = new WakeUPServiceLocator();
     WakeUPBindingStub wakeUpBinding = (WakeUPBindingStub)locator.getWakeUP();
            wakeUpBinding._setProperty(WakeUPBindingStub.ENDPOINT_ADDRESS_PROPERTY, 
        SessionHeader sh = new SessionHeader();
        sh.setSessionId(loginResult.getSessionId());
        wakeUpBinding.setHeader(new WakeUPServiceLocator().getServiceName().getNamespaceURI(),
                          "SessionHeader", sh);
        
        wakeUpBinding.SetUrl(loginResult.getServerUrl());
        return true;
    }

 The resulting binding does not work.  I continue to get the error:

No operation available for request {https://na5-api.salesforce.com/services/Soap/c/11.1/461600D70000000IVGU/schemas/class/WakeUP}wakeUP

This is the same error I received before I modified the hostname and the url then was:

"http://soap.sforce.com/schemas/class/WakeUP"

I had to add the setUrl method to the binding stub as it originally had the host hardcoded "http://soap.sforce.com/schemas/class/WakeUP".



SuperfellSuperfell
You're trying to hard. remove the code that sets the Url, and sets the ENDPOINT_ADDRESS_PROPERTY and it should work, all you need is the session header code.