質問

Webサービスを使用して、バックエンドシステムとSalesforceを統合しています。さまざまなURLで実行されている生産環境と舞台環境があります。コードが制作インスタンスで実行されているかどうかによって、Webサービスコールのエンドポイントを異なるようにする必要があります。

環境を検出するにはどうすればよいですか。

現在、ユーザーが「devsandbox」でユーザー名が終了するかどうかを確認するためにユーザーを検索して、環境を取得するためにクエリできるシステムオブジェクトを識別できなかったため、検討しています。

さらなる解明:

これを決定する必要がある場所は、Salesforceでボタンを選択したときに呼び出されるApexコード内にあります。私のカスタムコントローラーは、生産またはサンドボックスセールスフォース環境で実行されているかどうかを知る必要があります。

役に立ちましたか?

解決

For y'all finding this via search results, there is an important update. As Daniel Hoechst pointed out in another post, SF now directly provides sandbox vs. production information:

In Summer '14, (version 31.0), there is a new field available on the Organization object.

select Id, IsSandbox from Organization limit 1

From the release notes under New and Change Objects:

The Organization object has the following new read-only fields.

InstanceName
IsSandbox

他のヒント

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)

The current organization ID can be found with System.getOrganizationId()

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

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()

I know this is an old post, but just for the sake of people looking for an updated answer as of Spring '11 release there is a new method System.URL.getSalesforceBaseUrl().toExternalForm() that returns the current url.
You can work from there to get all the info you need.

Here's the link to docs: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_url.htm

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>

Sandboxes may have a personalized url (e.g. acme.cs1.my.salesforce.com), or might be hosting a visualforce page (cs2.visual.force.com) or both (acme.cs2.visual.force.com) so I use this method:

public static Boolean isRunningInSandbox() {
    String s  =  System.URL.getSalesforceBaseUrl().getHost();
    return (Pattern.matches('(.*\\.)?cs[0-9]*(-api)?\\..*force.com',s));
}   

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".

In your apex code you can use the following to get the instance of SF that you are in.

Keeping it dynamic will make sure you don't have to update your code when your org is migrated to a different instance.

String s  =  System.URL.getSalesforceBaseUrl().getHost();
//this will return "na1.salesforce.com"  or "na1-api.salesforce.com",
// where na1 is your instance of SF, and -api may be there depending on where you run this
s = s.substring(0,s.indexOf('.'));
if(s.contains('-'))
{
    s = s.substring(0,s.indexOf('-'));
}
system.debug(s);

There is a similar question on the Salesforce StackExchange for detecting if you are in a Sandbox or not - Can we determine if the Salesforce instance is production org or a Sandbox org?

In the solutions in search of a problem category, you could use the pod identifier from the OrgId to determine if you are dealing with a sandbox.

string podId = UserInfo.getOrganizationId().substring(3,4);
boolean isSandbox = 'TSRQPONMLKJZVWcefg'.contains(podId);
System.debug('IsSandbox: ' + isSandbox);

Caveat Confector: The big weakness here is that you will need to update the list of know sandbox pods as and when Salesforce brings new ones online (so it might be safer sticking with the other solutions).

You can use the following code block from Michael Farrington an authority on Salesforce.

Original blog post here: Michael Farrington: Where Am I Method

This method will return true if you are in a test or sandbox environment and false otherwise.

    public Static Boolean isSandbox(){

    String host = URL.getSalesforceBaseUrl().getHost();
    String server = host.substring(0,host.indexOf('.'));

    // It's easiest to check for 'my domain' sandboxes first 
    // even though that will be rare
    if(server.contains('--'))
        return true;

    // tapp0 is a unique "non-cs" server so we check it now
    if(server == 'tapp0')
        return true;

    // If server is 'cs' followed by a number it's a sandbox
    if(server.length()>2){
        if(server.substring(0,2)=='cs'){
            try{
                Integer.valueOf(server.substring(2,server.length()));
            }
            catch(exception e){
                //started with cs, but not followed by a number
                return false;
            }

            //cs followed by a number, that's a hit
            return true;
        }
    }

    // If we made it here it's a production box
    return false;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top