views:

565

answers:

4

I am integrating our back end systems with Salesforce using the web services. I have production and stage environments running on different URLs. I need to be able to have the endpoint of the web service call be different depending on whether the code is running in the production or sandbox Salesforce instance.

How do I detect the environment.

Currently I am considering looking up a user to see if there user name ends in 'devsandbox' as I have been unable to identify a system object that I can query to get the environment.

Further clarification:

The location I need to determine this is within the Apex code that is invoked when I select a button in Salesforce. My custom controller needs to know if it running in the production or sandbox Salesforce environment.

+1  A: 

The Login API call returns a sandbox element in the returned LoginResult structure that indicates if its a sandbox environment or not, from the WSDL.

        <complexType name="LoginResult">
            <sequence>
                <element name="metadataServerUrl" type="xsd:string" nillable="true"/>
                <element name="passwordExpired"   type="xsd:boolean" />
                <element name="sandbox"      type="xsd:boolean"/>
                <element name="serverUrl"         type="xsd:string" nillable="true"/>
                <element name="sessionId"         type="xsd:string" nillable="true"/>
                <element name="userId"           type="tns:ID" nillable="true"/>
                <element name="userInfo"         type="tns:GetUserInfoResult" minOccurs="0"/>
            </sequence>
        </complexType>
superfell
This would work on the back end but my problem is in my custom controller which needs to determine which back end web service to invoke
Craig Harris
A: 

I think the easiest way to do this would be to create a custom object in Salesforce, and then store a value indicating sandbox or production there. Your Apex code can then query that object. One suggestion would be to use Apex static constructors to load this information and cache it for the request.

Another thought I had (but hate to suggest) is to use an external service to determine where your Apex code is executing. This would probably be difficult to pull off, as every time the SalesForce server farm changes there is a change your code would break, but I just thought I'd throw this out there.

HttpRequest req = new HttpRequest();
req.setEndpoint('http://www.whatismyip.com/automation/n09230945.asp');
req.setMethod('GET');

Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());

You have to add "http://www.whatismyip.com" to the Remote Site settings to get this to work (Setup > Administration Setup > Security Controls > Remote Site Settings). This code should run in the debug window when you click "System Log".

Adam
I had already considered the first one but was concerned that this needs to be manually changed every time a sandbox is refreshed. The cost of missing this manual update is that stage/test data will go to production on the back end.The second option is intriguing but as you state not stable.
Craig Harris
+1  A: 

Based on the responses it appears that Salesforce does not have a system object that can tell me if my Apex code is running in production or a sandbox environment.

I am going to proceed based on the following assumptions:

  • I can read the organisation id of the current environment
  • The organisation id of my production system will always remain constant.
  • The organisation id of a sandbox will always be different to production (as they are unique)

My solution is to have my code compare the current org id to the constant value representing production.

Craig Harris
A: 

I'm performing necromancy here and the answer is already accepted, but maybe somebody will benefit from it...

Use one of these merge fields on your Visualforce page / S-Control:

{!$Api.Enterprise_Server_URL_180}, {!$Api.Partner_Server_URL_180}, {!$Api.Session_ID}

You can easily parse out organization ID out of them.

In Apex code: UserInfo.getOrganisationId()

eyescream