Java 使用SAP Cloud SDK版本3.2.0向OData服务发送POST请求时如何避免DestinationAccess异常
我正在开发一个使用SAP Cloud SDK版本3.2.0的Java应用程序。我有一个端点,它使用ResilienceDecorator的queueCallable异步处理请求;通过此服务,可以创建业务合作伙伴(BP)。我正在使用SoapUI进行压力测试,有时在发送多个请求(例如,50个请求)时,会生成DestinationAccessException。我不知道这个问题的原因是什么,有人能帮我找到解决办法吗 有时会显示以下消息: 目的地访问例外: com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: javax.naming.NoInitialContextException:无法实例化类: org.apache.naming.java.javaURLContextFactory[根异常为 java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory] 其他情况下,将显示以下消息: DestinationAccessException:名称没有目标 在任何已注册的加载程序中都可以找到“ErpQueryEndpoint” 这是我的类AccountController:Java 使用SAP Cloud SDK版本3.2.0向OData服务发送POST请求时如何避免DestinationAccess异常,java,odata,sap-cloud-platform,sap-cloud-sdk,Java,Odata,Sap Cloud Platform,Sap Cloud Sdk,我正在开发一个使用SAP Cloud SDK版本3.2.0的Java应用程序。我有一个端点,它使用ResilienceDecorator的queueCallable异步处理请求;通过此服务,可以创建业务合作伙伴(BP)。我正在使用SoapUI进行压力测试,有时在发送多个请求(例如,50个请求)时,会生成DestinationAccessException。我不知道这个问题的原因是什么,有人能帮我找到解决办法吗 有时会显示以下消息: 目的地访问例外: com.sap.cloud.sdk.cloud
public class AccountController {
@Autowired
AccountBF accountBF;
...
@RequestMapping(value = "/bp/create/extended", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> createBpExtended(@RequestBody BpCreateBasicRequest bpCreateRequest) throws IOException {
Object bpCreateBasicResponse = accountBF.bpCreateExtended(bpCreateRequest);
return ResponseEntity.ok(bpCreateBasicResponse);
}
}
公共类AccountController{
@自动连线
AccountBF AccountBF;
...
@RequestMapping(value=“/bp/create/extended”,method=RequestMethod.POST)
@应答器
公共响应Entity CreateBextended(@RequestBody BpCreateBasicRequest bpCreateRequest)引发IOException{
对象bpCreateBasicResponse=accountBF.bpCreateExtended(bpCreateRequest);
返回ResponseEntity.ok(bpCreateBasicResponse);
}
}
这是我的班级帐户bImpl:
public class AccountBFimpl implements AccountBF {
private ResilienceConfiguration conf;
...
public Object executeAsyncCall(BpCreateBasicRequest bpCreateRequest) {
LogMessage logMessage = new LogMessage();
...
JSONObject jsonResponse = null;
try {
ODataCreateRequestImpl createRequest = new ODataCreateRequestImpl("/sap/opu/odata/sap/ZAS_BP_CREATION_SRV",
"BP_DATASet", bodyAsMap, null, null, null, headersAsMap, null, false, null, null, false);
createRequest.execute("ErpQueryEndpoint");
jsonResponse = new JSONObject();
} catch (DestinationAccessException e ) {
System.out.println("DestinationAccessException: "+e.getMessage());
logMessage.setMessageContent("Creating the BP: " + bpCreateRequest.getNumeroId() + ". " +
" DestinationAccessException: "+e.getMessage());
writeMessageContent(logMessage);
} catch (HttpServerErrorException e ) {
System.out.println("HttpServerErrorException: " + e.getMessage());
logMessage.setMessageContent("Creating the BP: " + bpCreateRequest.getNumeroId() + ". " +
" HttpServerErrorException: "+e.getMessage());
writeMessageContent(logMessage);
} catch (Exception e ) {
System.out.println("Exception: " + e.getMessage());
logMessage.setMessageContent("Creating the BP: " + bpCreateRequest.getNumeroId() + ". " +
" Exception: "+e.getMessage());
writeMessageContent(logMessage);
}
...
return jsonResponse;
}
public Object bpCreateExtended(BpCreateBasicRequest bpCreateRequest) throws IOException {
LogMessage logMessage = new LogMessage();
logMessage.setMessageContent("Creating the BP: " + bpCreateRequest.getNumeroId() + ". " + "Entering the" +
" bpCreateExtended method");
writeMessageContent(logMessage);
this.conf = ResilienceConfiguration.of(AccountBFimpl.class);
Object response = null;
CompletableFuture<Object> futureFirstStep = ResilienceDecorator.queueCallable(() ->
executeAsyncCall(bpCreateRequest), conf);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
logMessage.setMessageContent("Creating the BP: " + bpCreateRequest.getNumeroId() + ". " +
" InterruptedException in sleep - bpCreateExtended: "+e.getMessage());
writeMessageContent(logMessage);
}
logMessage.setMessageContent("After create the BP: " + bpCreateRequest.getNumeroId() + ". " + "Leaving the" +
" bpCreateExtended method");
writeMessageContent(logMessage);
return (JSONObject) response;
}
}
公共类accountbImpl实现AccountBF{
私有弹性配置配置;
...
公共对象executeAsyncCall(BpCreateBasicRequest bpCreateRequest){
LogMessage LogMessage=新的LogMessage();
...
JSONObject jsonResponse=null;
试一试{
ODataCreateRequestImpl createRequest=新的ODataCreateRequestImpl(“/sap/opu/odata/sap/ZAS\u BP\u CREATION\u SRV”,
“BP_数据集”,bodyAsMap,null,null,null,headersAsMap,null,false,null,null,false);
createRequest.execute(“ErpQueryEndpoint”);
jsonResponse=新的JSONObject();
}捕获(目标访问异常e){
System.out.println(“DestinationAccessException:+e.getMessage());
logMessage.setMessageContent(“创建BP:+bpCreateRequest.getNumeroId()+”+
“DestinationAccessException:+e.getMessage());
writeMessageContent(日志消息);
}捕获(HttpServerErrorException){
System.out.println(“HttpServerErrorException:+e.getMessage());
logMessage.setMessageContent(“创建BP:+bpCreateRequest.getNumeroId()+”+
“HttpServerErrorException:”+e.getMessage());
writeMessageContent(日志消息);
}捕获(例外e){
System.out.println(“异常:+e.getMessage());
logMessage.setMessageContent(“创建BP:+bpCreateRequest.getNumeroId()+”+
“异常:”+e.getMessage());
writeMessageContent(日志消息);
}
...
返回jsonResponse;
}
公共对象bpCreateExtended(BpCreateBasicRequest bpCreateRequest)引发IOException{
LogMessage LogMessage=新的LogMessage();
logMessage.setMessageContent(“创建BP:+bpCreateRequest.getNumeroId()+”+“+”输入”+
“扩展方法”);
writeMessageContent(日志消息);
this.conf=ResilienceConfiguration.of(accountbImpl.class);
对象响应=null;
CompletableFuture futureFirstStep=ResilienceDecorator.queueCallable(()->
executeAsyncCall(bpCreateRequest),conf);
试一试{
时间单位。秒。睡眠(5);
}捕捉(中断异常e){
logMessage.setMessageContent(“创建BP:+bpCreateRequest.getNumeroId()+”+
睡眠中的InterruptedException-bpCreateExtended:+e.getMessage());
writeMessageContent(日志消息);
}
logMessage.setMessageContent(“创建BP之后:+bpCreateRequest.getNumeroId()+”+“+”离开”+
“扩展方法”);
writeMessageContent(日志消息);
返回(JSONObject)响应;
}
}
这是my pom.xml的内容:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atlantida.services</groupId>
<artifactId>account</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>atlantida</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.sap.cloud.sdk</groupId>
<artifactId>sdk-bom</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<java-version>1.8</java-version>
<springframework.version>5.1.8.RELEASE</springframework.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.11</junit.version>
<jackson-version>2.9.2</jackson-version>
<lombok.version>1.18.8</lombok.version>
<jcl.slf4j.version>1.7.12</jcl.slf4j.version>
<logback.version>1.1.3</logback.version>
<!-- if you are behind a proxy use the following two properties to configure your proxy. Default: None -->
<proxy.host />
<proxy.port />
<non.proxy.hosts />
<!-- Properties that are related to the SAP Cloud Platform. -->
<scp.sdkVersion>1.44.12</scp.sdkVersion>
<!-- this is the location of your local SAP CP Neo runtime -->
<scp.sdkInstallPath>${project.basedir}/scp/sdk-${scp.sdkVersion}</scp.sdkInstallPath>
<scp.sdkLocalServerContentPath>${project.basedir}/localServerContent</scp.sdkLocalServerContentPath>
<scp.sdkErpEndpoint>${scp.sdkInstallPath}/server/config_master/service.destinations/destinations/ErpQueryEndpoint</scp.sdkErpEndpoint>
<scp.sdkSymbolicLink>${project.basedir}/scp/sdk</scp.sdkSymbolicLink>
<scp.sdkNeoCmdExtension>.sh</scp.sdkNeoCmdExtension>
<scp.sdkNeoCmd>${scp.sdkInstallPath}/tools/neo${scp.sdkNeoCmdExtension}</scp.sdkNeoCmd>
<scp.sdkLocalServer>${scp.sdkInstallPath}/server</scp.sdkLocalServer>
<scp.skipInstallSdk>false</scp.skipInstallSdk>
<scp.skipDeploy>false</scp.skipDeploy>
<scp.skipPutDestination>false</scp.skipPutDestination>
<scp.skipRestart>false</scp.skipRestart>
<scp.skipRollingUpdate>true</scp.skipRollingUpdate>
<scp.vmArguments />
<scp.vmSize>lite</scp.vmSize>
<scp.vmMinProcesses>1</scp.vmMinProcesses>
<scp.vmMaxProcesses>1</scp.vmMaxProcesses>
<scp.app />
<scp.host />
<scp.account />
<scp.username />
<scp.password />
<!-- Required for SAP CP user session management and audit logging. -->
<scp.warImportPackage>com.sap.security.auth.service,com.sap.security.um.service.api,com.sap.core.service.auditlog.impl,com.sap.cloud.auditlog,com.sap.cloud.auditlog.exception,com.sap.cloud.auditlog.extension</scp.warImportPackage>
<!-- Defines whether the deployment is productive or not. -->
<productive />
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<!-- Bridge logging from JCL to SLF4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${jcl.slf4j.version}</version>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-neo</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.servicesdk</groupId>
<artifactId>odatav2-connectivity-sdk3</artifactId>
<version>1.36.2</version>
</dependency>
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>security-servlet</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sap.cloud</groupId>
<artifactId>neo-javaee7-wp-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>atlantida</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>SAP Cloud SDK Project Structure Checks</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.5</version>
</requireMavenVersion>
<requireJavaVersion>
<version>${java.version}</version>
</requireJavaVersion>
<reactorModuleConvergence />
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<attachClasses>true</attachClasses>
<archive>
<manifestEntries>
<Version>${project.version}</Version>
<Import-Package>${scp.warImportPackage}</Import-Package>
</manifestEntries>
</archive>
<webResources>
<resources>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resources>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sap.cloud</groupId>
<artifactId>neo-javaee7-wp-sdk</artifactId>
<version>${scp.sdkVersion}</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>${scp.sdkInstallPath}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</plugin>
<!-- Plugin for deployment to SAP Cloud Platform Neo. -->
<plugin>
<groupId>com.sap.cloud</groupId>
<artifactId>neo-javaee7-wp-maven-plugin</artifactId>
<version>${scp.sdkVersion}</version>
<executions>
<execution>
<id>stop</id>
<phase>install</phase>
<goals>
<goal>stop</goal>
</goals>
<configuration>
<skip>${scp.skipRestart}</skip>
</configuration>
</execution>
<execution>
<id>deploy</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<skip>${scp.skipDeploy}</skip>
<vmArguments>${scp.vmArguments}</vmArguments>
</configuration>
</execution>
<execution>
<id>start</id>
<phase>install</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<skip>${scp.skipRestart}</skip>
</configuration>
</execution>
<execution>
<id>rolling-update</id>
<phase>install</phase>
<goals>
<goal>rolling-update</goal>
</goals>
<configuration>
<skip>${scp.skipRollingUpdate}</skip>
</configuration>
</execution>
</executions>
<configuration>
<sdkInstallPath>${scp.sdkInstallPath}</sdkInstallPath>
<skip>${scp.skipInstallSdk}</skip>
<application>${scp.app}</application>
<source>${project.build.directory}/${project.build.finalName}.war</source>
<vmArguments>${scp.vmArguments}</vmArguments>
<size>${scp.vmSize}</size>
<minimumProcesses>${scp.vmMinProcesses}</minimumProcesses>
<maximumProcesses>${scp.vmMaxProcesses}</maximumProcesses>
<host>${scp.host}</host>
<account>${scp.account}</account>
<user>${scp.username}</user>
<password>${scp.password}</password>
<synchronous>true</synchronous>
<httpProxyHost>${proxy.host}</httpProxyHost>
<httpProxyPort>${proxy.port}</httpProxyPort>
<httpsProxyHost>${proxy.host}</httpsProxyHost>
<httpsProxyPort>${proxy.port}</httpsProxyPort>
<consoleCommand />
<consoleHttpProxyHost>${proxy.host}</consoleHttpProxyHost>
<consoleHttpProxyPort>${proxy.port}</consoleHttpProxyPort>
<consoleHttpsProxyHost>${proxy.host}</consoleHttpsProxyHost>
<consoleHttpsProxyPort>${proxy.port}</consoleHttpsProxyPort>
<dbsystem />
<dbSize />
<dbUser />
</configuration>
</plugin>
<!-- Plugin for deployment to local runtime of SAP Cloud Platform Neo. -->
<plugin>
<groupId>com.sap.cloud.sdk.plugins</groupId>
<artifactId>scp-neo-maven-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<sdkPlugin>neo-javaee7-wp-maven-plugin</sdkPlugin>
<sdkPluginVersion>${scp.sdkVersion}</sdkPluginVersion>
<sdkInstallPath>${scp.sdkInstallPath}</sdkInstallPath>
<sdkSymbolicLink>${scp.sdkSymbolicLink}</sdkSymbolicLink>
<sdkServerContentPath>${scp.sdkLocalServerContentPath}</sdkServerContentPath>
<source>${project.build.directory}/${project.build.finalName}.war</source>
<proxyHost>${proxy.host}</proxyHost>
<proxyPort>${proxy.port}</proxyPort>
<httpNonProxyHosts>${non.proxy.hosts}</httpNonProxyHosts>
<destinations>
<destination>
<path>${scp.sdkErpEndpoint}</path>
<username>achacon</username>
<password>*******</password>
<url>http://crmdev:4431</url>
</destination>
</destinations>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>com.sap.cloud.sdk.plugins</groupId>
<artifactId>usage-analytics-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>usage-analytics</goal>
</goals>
<configuration>
<skipUsageAnalytics>false</skipUsageAnalytics>
<generateSalt>true</generateSalt>
<!--
Note: A random salt is auto-generated once the project is built for the first time.
Please keep the generated salt in the POM file, for example, when pushing to git.
To learn more, visit: https://blogs.sap.com/2018/10/23/usage-analytics-s4sdk/
-->
<salt>5d5e4e1e8a5f05d547fe8880f65173bda150a670f91f3657b970eaa9e7a4d392</salt>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<!--
Profiles that are used to set the Neo SDK "neo" command extension ("neo.sh" or "neo.cmd")
-->
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<scp.sdkNeoCmdExtension>.bat</scp.sdkNeoCmdExtension>
</properties>
</profile>
<profile>
<id>unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<scp.sdkNeoCmdExtension>.sh</scp.sdkNeoCmdExtension>
</properties>
</profile>
<!-- Profile setting properties for deploying to the local SAP CP runtime. -->
<profile>
<id>local-deploy</id>
<activation>
<property>
<name>!scp.app</name>
</property>
</activation>
<properties>
<scp.skipInstallSdk>true</scp.skipInstallSdk>
<scp.skipDeploy>true</scp.skipDeploy>
<scp.skipPutDestination>true</scp.skipPutDestination>
<scp.skipRestart>true</scp.skipRestart>
<scp.skipRollingUpdate>true</scp.skipRollingUpdate>
</properties>
</profile>
<!-- Profile setting properties for deploying a productive version to SAP CP. -->
<profile>
<id>scp-deploy</id>
<activation>
<property>
<name>productive</name>
</property>
</activation>
<properties>
<scp.skipInstallSdk>false</scp.skipInstallSdk>
<scp.skipDeploy>true</scp.skipDeploy>
<scp.skipPutDestination>false</scp.skipPutDestination>
<scp.skipRestart>true</scp.skipRestart>
<scp.skipRollingUpdate>false</scp.skipRollingUpdate>
</properties>
</profile>
</profiles>
</project>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
4.0.0
com.atlantida.services
谢谢你的好问题。我注意到的第一件事是,您使用的SDK版本已经非常过时,当前版本是3.14.0
,您现在使用的是3.2.0
。我们对每个版本都做了很多修复,我建议
切换到依赖项中的最新版本。看看我们的
关于弹性,很难确切地说出负载测试可能失败的原因,因为您通过调用SDK团队未维护的非类型化请求生成器在相当低的级别上使用SDK。对于Odata V2ODataCreateRequestImpl
而言,它是一个依赖项,不用于直接消费。我们公开它只是为了边缘情况和方便
使用SDK的一种更可靠的方法是,首先从服务定义生成虚拟数据模型,然后构建类型化请求。这些应该更多
实现可靠且易于调试
- 您是否可以选择先生成虚拟数据模型,然后使用更好的方法生成请求李>
我将看看是否能找到更多关于这个案例的想法,同时更新SDK版本并检查是否可以使用上面教程中提到的CRUD类型化请求生成器将是一个好主意
如果您有任何其他详细信息,可以与我们分享。Th
CompletableFuture<Object> futureFirstStep = ResilienceDecorator.queueCallable(() ->
executeAsyncCall(bpCreateRequest), conf);
new Thread(() -> {
some instruction;
}).start();