如何检测 Salesforce 中的环境?
-
19-09-2019 - |
题
我正在使用 Web 服务将我们的后端系统与 Salesforce 集成。我有在不同 URL 上运行的生产环境和阶段环境。我需要能够使 Web 服务调用的端点有所不同,具体取决于代码是在生产实例还是沙箱 Salesforce 实例中运行。
如何检测环境。
目前,我正在考虑查找用户以查看用户名是否以“devsandbox”结尾,因为我无法识别可以查询以获取环境的系统对象。
进一步澄清:
我需要确定这一点的位置位于我在 Salesforce 中选择按钮时调用的 Apex 代码内。我的自定义控制器需要知道它是否在生产环境或沙箱 Salesforce 环境中运行。
解决方案
对于通过搜索结果找到此内容的人来说,有一个重要的更新。正如丹尼尔·赫斯特 (Daniel Hoechst) 在《 另一个帖子, ,SF现在直接提供沙盒vs。生产信息:
在2014年夏季(版本31.0),组织对象上有一个新字段。
从组织限制 1 中选择 Id、IsSandbox
从“新建和更改对象”下的发行说明中:
The Organization object has the following new read-only fields.
InstanceName
IsSandbox
其他提示
根据响应,Salesforce 似乎没有系统对象可以告诉我我的 Apex 代码是在生产环境还是沙箱环境中运行。
我将基于以下假设进行操作:
- 我可以读取当前环境的组织id
- 我的生产系统的组织ID将始终保持不变。
- 沙箱的组织 ID 始终与生产环境不同(因为它们是唯一的)
当前组织 ID 可以通过以下方式找到 System.getOrganizationId()
我的解决方案是让我的代码将当前组织 ID 与代表生产的常量值进行比较。
我在这里表演巫术和答案已被接受,但也许有人会从中受益......
使用这些合并您的Visualforce页/ S-控制的领域之一:
{!$Api.Enterprise_Server_URL_180}, {!$Api.Partner_Server_URL_180}, {!$Api.Session_ID}
可以很容易地分析出组织ID了出来。
在顶点的代码: UserInfo.getOrganisationId()一>
我知道这是一个古老的职位,但只是为人们寻找更新的答案,'11春季发行的缘故,有一种新的方法 System.URL.getSalesforceBaseUrl()。toExternalForm()返回当前的URL。结果 你可以从那里得到你需要的所有信息。
这里的链接到文档:的http:// WWW。 salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_url.htm
在登录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>
沙箱可以具有个性化的URL(例如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));
}
我觉得这样做将在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 ”到远程站点设置得到这个工作(设置>管理设置>安全控制>远程站点设置)。此代码应在调试窗口中运行,当你点击“系统日志”。
在你的顶点代码,你可以使用下面让你在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);
Salesforce StackExchange 上有一个类似的问题,用于检测您是否位于沙箱中 - 我们能否确定 Salesforce 实例是生产组织还是沙盒组织?
在里面 寻找问题类别的解决方案, ,您可以使用 OrgId 中的 pod 标识符来确定您是否正在处理沙箱。
string podId = UserInfo.getOrganizationId().substring(3,4);
boolean isSandbox = 'TSRQPONMLKJZVWcefg'.contains(podId);
System.debug('IsSandbox: ' + isSandbox);
注意事项: 这里最大的弱点是,当 Salesforce 将新的沙箱 Pod 上线时,您需要更新已知沙箱 Pod 的列表(因此坚持使用其他解决方案可能更安全)。
可以使用从迈克尔法林顿以下代码块上的Salesforce的权威。
在这里原始博客文章:迈克尔·法林顿:我在哪里方法
如果你在一个测试或沙箱环境,否则为假。
此方法将返回真 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;
}