如何在Salesforce中检测环境?

时间:2009-10-02 04:20:53

标签: salesforce sandbox apex-code

我正在使用Web服务将我们的后端系统与Salesforce集成。我在不同的URL上运行生产和舞台环境。我需要能够使Web服务调用的端点不同,具体取决于代码是在生产环境还是沙箱Salesforce实例中运行。

如何检测环境。

目前我正在考虑查找用户以查看用户名是否以'devsandbox'结尾,因为我无法识别我可以查询以获取环境的系统对象。

进一步澄清:

我需要确定的位置在我在Salesforce中选择按钮时调用的Apex代码中。我的自定义控制器需要知道它是否在生产或沙箱Salesforce环境中运行。

10 个答案:

答案 0 :(得分:13)

对于你们通过搜索结果找到这个,有一个重要的更新。正如Daniel Hoechst在another post中指出的那样,SF现在直接提供沙箱与生产信息:

  

在2014年夏天,(版本31.0),有一个新的领域   组织对象。

     

从组织限制1中选择Id,IsSandbox

     

从“新建和更改对象”下的发行说明:

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

InstanceName
IsSandbox

答案 1 :(得分:12)

根据回复,看来Salesforce没有可以告诉我Apex代码是在生产环境还是沙箱环境中运行的系统对象。

我将基于以下假设继续进行:

  • 我可以阅读当前环境的组织ID
  • 我的生产系统的组织ID将始终保持不变。
  • 沙箱的组织ID将始终与生产不同(因为它们是唯一的)

可以使用System.getOrganizationId()

找到当前的组织ID

我的解决方案是让我的代码将当前的组织ID与代表生产的常量值进行比较。

答案 2 :(得分:3)

我在这里表现出死灵,答案已被接受,但也许有人会从中受益......

在Visualforce页面/ S-Control上使用其中一个合并字段:

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

您可以轻松地从中解析出组织ID。

在Apex代码中:UserInfo.getOrganisationId()

答案 3 :(得分:3)

我知道这是一篇旧文章,但仅仅是为了寻找更新答案的人,从Spring '11版本开始,有一种新方法 System.URL.getSalesforceBaseUrl()。toExternalForm()返回当前网址 您可以从那里获得所需的所有信息。

以下是docs的链接:http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_url.htm

答案 4 :(得分:2)

Login API调用在返回的LoginResult结构中返回一个沙箱元素,该元素从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>

答案 5 :(得分:2)

沙箱可能有个性化网址(例如acme.cs1.my.salesforce.com),或者可能托管visualforce页面(cs2.visual.force.com)或两者(acme.cs2.visual.force.com )所以我使用这种方法:

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

答案 6 :(得分:0)

我认为最简单的方法是在Salesforce中创建一个自定义对象,然后在那里存储一个指示沙箱或生产的值。然后,您的Apex代码可以查询该对象。一个建议是使用Apex静态构造函数来加载此信息并为请求缓存它。

我有另一种想法(但讨厌建议)是使用外部服务来确定Apex代码的执行位置。这可能很难实现,因为每次SalesForce服务器场发生更改时,代码都会发生变化,但我只是想把它扔出去。

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

您必须将“http://www.whatismyip.com”添加到远程站点设置才能使其正常工作(设置&gt;管理设置&gt;安全控制&gt;远程站点设置)。单击“系统日志”时,此代码应在调试窗口中运行。

答案 7 :(得分:0)

在您的顶级代码中,您可以使用以下内容来获取您所在的SF实例。

保持动态将确保您的组织迁移到其他实例时无需更新代码。

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

答案 8 :(得分:0)

Salesforce StackExchange上有一个类似的问题,用于检测您是否在Sandbox中 - Can we determine if the Salesforce instance is production org or a Sandbox org?

solutions in search of a problem category中,您可以使用OrgId中的pod标识符来确定您是否正在处理沙箱。

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

Caveat Confector:这里的一大弱点是,当Salesforce在线提供新的沙盒时,您需要更新已知沙箱的列表(因此可能更安全地坚持使用其他解决方案) 。

答案 9 :(得分:0)

您可以使用Michael Farrington的以下代码块作为Salesforce的权限。

原创博客文章:Michael Farrington: Where Am I Method

如果您处于测试或沙箱环境中,则此方法将返回true,否则返回false。

    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;
}