Technical Articles
Step 4 with SAP Cloud SDK: Calling an OData Service with the Virtual Data Model
Disclaimer:
This blog post is only applicable for the latest version 2 of the SAP Cloud SDK. You can find an updated tutorial for version 3 over at our tutorial page.
The following steps will explain how to use the SAP Cloud SDK’s Virtual Data Model (VDM) to call OData services of an SAP S/4HANA system.
Note: This post is part of a series. For a complete overview visit the SAP Cloud SDK Overview.
Goal of this blog post
In this tutorial, we will do the following:
- Explain the SAP S/4HANA Virtual Data Model provided as part of the SAP Cloud SDK
- Enhance the HelloWorld project stub to call an existing OData service via the VDM.
- Deploy the project on
- SAP Cloud Platform Neo
- SAP Cloud Platform Cloud Foundry
- Write an integration test
If you want to follow this tutorial, we highly recommend checking out Step 1 (Setup) and Step 2 (HelloWorld on SAP Cloud Platform Neo) or Step 3 (HelloWorld on SAP Cloud Platform CloudFoundry), respectively, depending on your choice of platform. You will not need any additional software besides the setup explained in the first part of the series. The application will run on your local machine and can be deployed to Cloud Platform.
If you would like to know more about communication management and identity & access management artifacts in S/4HANA Cloud, please follow the Deep Dive on this topic. We also highly recommend as further reading the deep dive on the OData Virtual Data Model used in this blog post. The VDM provides very easy access to OData endpoints of an SAP S/4HANA system for services published in the SAP API Business Hub.
Note: This tutorial requires access to an SAP S/4HANA system (see prerequisites below).
Prerequisites
In order to execute this tutorial successfully, we assume a working and reachable system of SAP S/4HANA on-premise or S/4HANA Cloud. You may substitute the presented business partner service by any other API published on the SAP API BusinessHub.
If you do not have an S/4HANA system at hand, you may be interested to study the mocking capabilities provided by the VDM as explained in the corresponding blog post.
Please note that depending on the platform (Neo or CloudFoundry) you are using, the configuration to the respective S/4HANA system might be different. In the following, we list the methods by which you can access your system.
SAP Cloud Platform, Neo | SAP Cloud Platform, Cloud Foundry | |
S/4HANA on-premise | SAP Cloud Connector required with HTTP Destination | SAP Cloud Platform Connectivity and Cloud Connector |
S/4HANA Cloud |
Direct Connection with BASIC Auth (technical user) Direct Connection with SAMLOAuthBearer (PrincipalPropagation with BusinessUser) |
Direct Connection with BASIC Auth (technical user, used below) |
Note that your application code is not dependent on your choice. Using the SAP Cloud SDK, you can write your code once and it is capable of dealing with all different authentication and connectivity options.
Virtual Data Model
This section explains the concepts of the S/4HANA Virtual Data Model. If you would like to first implement the S/4HANA integration, jump ahead to the next section and revisit the content of this section later.
The data stored in an S/4HANA system is inherently complexly structured and therefore difficult to query manually. Therefore, HANA introduced a Virtual Data Model (VDM) that aims to abstract from this complexity and provide data in a semantically meaningful and easy to consume way. The preferred way to consume data from an S/4HANA system is via the OData protocol. While BAPIs are also supported for compatibility reasons, OData should always be your first choice. You can find a list of all the available OData endpoints for S/4HANA Cloud systems in SAP’s API Business Hub.
The SAP Cloud SDK now brings the VDM for OData to the Java world to make the type-safe consumption of OData endpoints even more simple! The VDM is generated using the information from SAP’s API Business Hub. This means that it’s compatible with every API offered in the API Business Hub and therefore also compatible with every S/4HANA Cloud system.
The manual way to OData
Let’s take a look at typical code we could write to access any OData service using the SAP Cloud Platform SDK for service development. Here, we retrieve a list of business partners from an S/4HANA system:
final ErpConfigContext configContext = new ErpConfigContext();
final List<MyBusinessPartnerType> businessPartners = ODataQueryBuilder
.withEntity("/sap/opu/odata/sap/API_BUSINESS_PARTNER",
"A_BusinessPartner")
.select("BusinessPartner",
"LastName",
"FirstName",
"IsMale",
"IsFemale",
"CreationDate")
.build()
.execute(configContext)
.asList(MyBusinessPartnerType.class);
The ODataQueryBuilder represents a simple and generic approach to consuming OData services in your application and is well suited to support arbitrary services. It is a big step forward from manually building up an HTTP request to an OData service and processing the results in your code, and is used internally by the SAP Cloud SDK. In turn, the ODataQueryBuilder also uses concepts of the SAP Cloud SDK to simplify communication with systems, which are referenced by an ErpConfigContext.
Nevertheless, there are quite a few pitfalls you can fall into when using the plain ODataQueryBuilder approach to call OData services:
- For
.withEntity("/sap/opu/odata/sap/API_BUSINESS_PARTNER", "A_BusinessPartner")
you already need to know three things: the OData endpoints service path (/sap/opu/odata/sap
), the endpoints name (API_BUSINESS_PARTNER
) and the name of the entity collection (A_BusinessPartner
) as defined in the metadata of the endpoint. - Then, when you want to select specific attributes from the BusinessPartner entity type with the
select()
function, you need to know how these fields are named. But since they are only represented as strings in this code, you need to look at the metadata to find out how they’re called. The same also applies for functions likeorder()
andfilter()
. And of course using strings as parameters is prone to spelling errors that your IDE most likely won’t be able to catch for you. - Finally, you need to define a class such as MyBusinessPartnerType with specific annotations that represents the properties and their types of the result. For this you again need to know a lot of details about the OData service.
Virtual Data Model: The new way to OData
Now that we have explained the possible pitfalls of the current aproach, let’s take a look at how the OData VDM of the SAP Cloud SDK simplifies the same task, as the SDK is able to incorporate more knowledge about the system that is being called.
final List<BusinessPartner> businessPartners =
new DefaultBusinessPartnerService()
.getAllBusinessPartner()
.select(BusinessPartner.BUSINESS_PARTNER,
BusinessPartner.LAST_NAME,
BusinessPartner.FIRST_NAME,
BusinessPartner.IS_MALE,
BusinessPartner.IS_FEMALE,
BusinessPartner.CREATION_DATE)
.execute();
Using the OData VDM we now have access to an object representation of a specific OData service, in this case the DefaultBusinessPartnerService
(default implementation of the interface BusinessPartnerService
). So now there’s no more need to know the endpoint’s service path, service name or entity collection name. We can call this service’s getAllBusinessPartner()
function to retrieve a list of all the business partners from the system.
Now take a look at the select()
function. Instead of passing strings that represent the field of the entity, we can simply use the static fields provided by the BusinessPartner class. So not only have we eliminated the risk of spelling errors, we also made it type-safe! Again, the same applies for filter()
and orderBy()
. For example, filtering to male business partners becomes as easy as .filter(BusinessPartner.IS_MALE.eq(true))
– note the type-safe comparison.
An additional benefit of this approach is discoverability. Since everything is represented as code, you can simply use your IDE’s autocompletion features to see which functions a service supports and which fields an entity consists of: start by looking at the different services that are available in the package com.sap.cloud.sdk.s4hana.datamodel.odata.services
, instantiate the default implementation of the service you need (class name prefixed with Default
), and then look for the methods of the service class that represent the different available operations. Based on this, you can choose the fields to select and filters to apply using the fields of the return type.
Each service is described by a Java interface, for example, BusinessPartnerService
. The SDK provides a default, complete implementation of each service interface. The corresponding implementation is available in a class whose name is the name of the interface prefixed with Default
, for example, DefaultBusinessPartnerService
. You can either simply instantiate that class, or use dependency injection with a corresponding Java framework (covered in Step 22 of our tutorial series). The benefit of the interfaces is better testing and extensibility support.
To sum up the advantages of the OData VDM:
- No more hardcoded strings
- No more spelling errors
- Type safety for functions like filter, select and orderBy
- Java data types for the result provided out of the box, including appropriate conversions
- Discoverability by autocompletion
- SAP S/4HANA services can be easily mocked during testing based on the service interface in Java (see tutorial Step 19: Mocking S/4HANA calls)
The VDM supports retrieving entities by key and retrieving lists of entities alongwith filter()
, select()
, orderBy()
, top()
and skip()
. You can also resolve navigation properties on demand or eagerly (expand, see Step 22). The VDM also gives easy access to create (see Step 20), update, and delete operations as well as function imports.
For any OData service not part of SAP’s API Business Hub, the ODataQueryBuilder still is the goto approach for consumption.
Write the BusinessPartnerServlet
The SAP Cloud SDK provides simple and convenient ways to access your ERP systems out of the box. In this example we will implement an endpoint that performs an OData query to SAP S/4HANA in order to retrieve a list of business partners from our ERP system. More specifically, we want to retrieve all persons (a specific kind of business partner) with their name and a few additional properties.
To get started open your previously created Hello World project (in our case this is called firstapp) and create a new file called BusinessPartnerServlet.java
in the following location:
./application/src/main/java/com/sap/cloud/sdk/tutorial/BusinessPartnerServlet.java
package com.sap.cloud.sdk.tutorial;
import com.google.gson.Gson;
import org.slf4j.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.odatav2.connectivity.ODataException;
import com.sap.cloud.sdk.s4hana.datamodel.odata.helper.Order;
import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.BusinessPartner;
import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;
@WebServlet("/businesspartners")
public class BusinessPartnerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = CloudLoggerFactory.getLogger(BusinessPartnerServlet.class);
private static final String CATEGORY_PERSON = "1";
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
try {
final List<BusinessPartner> businessPartners =
new DefaultBusinessPartnerService()
.getAllBusinessPartner()
.select(BusinessPartner.BUSINESS_PARTNER,
BusinessPartner.LAST_NAME,
BusinessPartner.FIRST_NAME,
BusinessPartner.IS_MALE,
BusinessPartner.IS_FEMALE,
BusinessPartner.CREATION_DATE)
.filter(BusinessPartner.BUSINESS_PARTNER_CATEGORY.eq(CATEGORY_PERSON))
.orderBy(BusinessPartner.LAST_NAME, Order.ASC)
.top(10)
.execute();
response.setContentType("application/json");
response.getWriter().write(new Gson().toJson(businessPartners));
} catch (final ODataException e) {
logger.error(e.getMessage(), e);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().write(e.getMessage());
}
}
}
The code is fairly simple. In the servlet GET method, we initialize an instance of the BusinessPartnerService
to prepare the query to S/4HANA with the help of the SDK’s Virtual Data Model. We call the method getAllBusinessPartners
, which represents the operation of the OData service that we want to call. WIth the fluent query helper returned by this method, we can gradually build up the query:
- we select the fields of the
BusinessPartner
that we want to retrieve (if we leave out this part, all fields will be returned), - filter for business partners of category Person (code
"1"
), and - order by the last name of the business partner.
Finally, having prepared the query, we call the execute
method. This method does a lot of the heavy lifting necessary to connect to an S/4HANA system and relieves us as developers from dealing with complex aspects such as:
- the configuration which system to connect to (in a multi-tenant environment) – by transparently accessing the destination service of SAP Cloud Platform,
- the connectivity to this system, which may reside on-premise behind a corporate firewall, – by means of the connectivity service and the optional Cloud Connector, and
- the authentication to this system using potentially vastly different authentication flows (basic authentication, principal propagation, OAuth2).
The SAP Cloud SDK provides all of these capabilities with a simple interface and allows customers (tenants) of your application to configure the connection to their system. We will discuss the configuration below when deploying the project.
The execute
method of the VDM returns the query result as a navigatable list of type BusinessPartner
, which represents the entity type of the response in a type-safe manner. We declare the servlet’s response as JSON content and transform the result into a JSON response.
Any ODataException
thrown by the OData call is caught and logged, before returning an error response.
Deploying the Project
Depending on your chosen archetype and SAP Cloud Platform setup you can deploy the project on either SAP Cloud Platform Neo or SAP Cloud Platform Cloud Foundry. If you face any problem with connecting to OData please find the troubleshooting paragraph at the end.
On SAP Cloud Platform Neo
If you have started your project on SAP Cloud Platform Neo (step 2), you can now deploy your application to your local Neo platform using the following maven goals:
cd /path/to/firstapp
mvn clean install
mvn scp:clean scp:push -pl application -Derp.url=https://URL
Replace URL
with the URL to your SAP ERP system (host and, if necessary, port).
Note: the -pl
argument defines the location in which the Maven goals will be executed.
Maven will then prompt you for your username and password that is going to be used to connect to SAP S/4HANA. Alternatively, you can also set these values as command parameters: -Derp.username=USER -Derp.password=PASSWORD
If you now deploy the project with the Maven command and visit the page http://localhost:8080/businesspartners
you should be seeing a list of business partners that was retrieved from the ERP system. Note: Please login with test
/ test
).
On SAP Cloud Platform Cloud Foundry
If you have started your project on SAP Cloud Platform Cloud Foundry (step 3), you need to supply the destination of your SAP S/4HANA system before you deploy the new version to Cloud Foundry or run the application on the local server.
Run on a Local Server
As mentioned in Step 3 of this tutorial series, you can run the project on a local TomEE server. Here, you need to supply the destinations as an environment variable on your local machine (replace set
with the corresponding commands to define environment variables on your command shell).
set destinations=[{name: "ErpQueryEndpoint", url: "https://URL", username: "USER", password: "PASSWORD"}]
Please change the values URL
, USER
and PASSWORD
accordingly.
Afterwards, re-build and start the server as follows:
cd /path/to/firstapp
mvn clean install
mvn tomee:run -pl application
Visit http://localhost:8080/businesspartners to see your new feature in action.
Note: You can also add more ERP endpoints to this JSON representation, following the same schema. However, please note that “ErpQueryEndpoint” corresponds to the destination used by default by the execute method of the VDM.
Connecting to SAP S/4HANA from SAP Cloud Platform Cloud Foundry
In order to perform queries against your ERP system when the application is deployed on Cloud Foundry, you have to inform Cloud Foundry about the location of your ERP endpoint.
To do this, you can either supply the same environment variable destinations
that we used for the local deployment above to the Cloud Foundry application, or use the destination service of SAP Cloud Platform Cloud Foundry. Using the destination service is the recommended approach, because it already handles important aspects related to multi-tenancy, connectivity and security and is transparently integrated into the SAP Cloud SDK. Therefore, we explain how to use the destination service in detail below.
Nevertheless, there may be circumstances that make the approach via the environment variable easier to use or otherwise preferable for initial testing. To set the environment variable using the Cloud Foundry command line interface (CLI), execute the following command:
cf set-env firstapp destinations '[{name: "ErpQueryEndpoint", url: "https://URL", username: "USER", password: "PASSWORD"}]'
Again, supply the correct values for your S/4HANA system. Afterwards, rebuild and deploy the application to Cloud Foundry (see below). Depending on your command line interface (for example, on Windows), you may need to use double quotes instead of single quotes and escape the double quotes:
cf set-env firstapp destinations "[{name: \"ErpQueryEndpoint\", url: \"https://URL\", username: \"USER\", password: \"PASSWORD\"}]"
Whenever this environment variable is set, the SAP Cloud SDK will use it to determine destinations. Make sure to delete it with cf unset-env firstapp destinations
as soon as you are done with the initial testing and when you want to use the real destination service.
Using the Destination Service on SAP Cloud Platform Cloud Foundry
For the recommended approach of using the destination service to configure the connection to your SAP S/4HANA system, proceed as follows. Note that this requires version 1.6.0 or higher of the SAP Cloud SDK.
Subscribe to Services
The destination handling is available as a service on Cloud Foundry. You need to create an instance of that service and bind it to your application in order to use the destination service. Additionally, you need an instance of the Authorization and Trust Management (xsuaa) service.
Use the Cloud Foundry CLI to create the two required service instances:
cf create-service xsuaa application my-xsuaa
cf create-service destination lite my-destination
This creates two service instances in your space: one instance named my-xsuaa
for the xsuaa
service with service plan application
, and a second instance named my-destination
for the destination
service (plan lite
).
To bind the two newly created service instances to your application when it is deployed, adapt the manifest.yml
file by adding the two instances to the services section at the end. The remainder of the file remains as before:
---
applications:
- name: firstapp
memory: 768M
host: firstapp-D123456
path: application/target/firstapp-application.war
buildpack: sap_java_buildpack
env:
TARGET_RUNTIME: tomee
JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:96m..'
SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'
ALLOW_MOCKED_AUTH_HEADER: true
services:
- my-destination
- my-xsuaa
# - my-application-logs
# - my-connectivity
Please make sure to have the host
property declared with a unique name of your choice. The recommended way is to include the username as suffix. The hostname will later be used as subdomain of a publicly reachable route. Since this is a setup with multiple, dedicated instances, a random-route
should be omitted.
As of version 2.0.0 of the Cloud SDK you are required to set an environment variable to enable unauthorized access to your web service: ALLOW_MOCKED_AUTH_HEADER
. When the variable is explicitly set to true, the SDK will fall back to providing mock tenant and user information when no actual tenant information is available. This setting must never be enabled in productive environments. It is only meant to make testing easier if you do not yet implement the authentication mechanisms of Cloud Foundry. If you want to learn more about authorizing user access in a productive environment, please find Step 7: Securing Your Application.
With this, the setup is complete and we can re-deploy the application. However, we still need to configure the destination to our SAP S/4HANA system. We will do this in the next section and then deploy the application to Cloud Foundry.
Configure Destinations
Customers of our application can use the Cloud Platform cockpit to configure destinations. We will use the cockpit to define our destination as well.
- Navigate to the Cloud Foundry subaccount within your global account that you have used before to deploy the application (see Step 3). In case of a trial account, the subaccount will be called trial by default.
- In the menu on the left, expand Connectivity and select Destinations.
- Click on New Destination and enter the following values into the input fields:
- Name:
ErpQueryEndpoint
(this is the destination accessed by default by the SAP Cloud SDK) - URL:
https://URL
(URL to your SAP S/4HANA system) - Authentication: choose BasicAuthentication
- Provide credentials of your technical user in the User and Password fields.
- Leave the other fields unchanged.
- Name:
- Click on Save.
Afterwards, the destination should look as follows.
Please note that the above settings represent the setup for a connection to SAP S/4HANA Cloud via a technical user (communication user). Depending on your setup and requirements, you may want to use a different ProxyType (OnPremise when using the Cloud Connector) or a different means of authentication.
Deploy to Cloud Foundry
Now you can deploy your application to Cloud Foundry using the Cloud Foundry CLI (command line interface):
cd /path/to/firstapp
mvn clean install
cf push
Access the new servlet at https://YOUR-ROUTE/businesspartners
.
If you change the destinations afterwards, you need to at least restart (or restage) your application to make sure that the changes become effective due to caching:
cf restart firstapp
Integration Test for BusinessPartnerServlet
To construct an extensible integration test for the newly created BusinessPartnerServlet, the following items will be prepared:
- Adjustment: Maven pom file
- New: test class
- New: JSON Schema for servlet response validation
- New: systems.json and credentials
Adjustment: Maven pom file
First, let’s adjust the Maven pom file of the integrations-tests sub module, by adding a dependency for JSON schema validation:
./integration-tests/pom.xml
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>3.0.6</version>
<scope>test</scope>
</dependency>
New: test class
Navigate to the integration-tests project and create a new class:
./integration-tests/src/test/java/com/sap/cloud/sdk/tutorial/BusinessPartnerServletTest.java
package com.sap.cloud.sdk.tutorial;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.module.jsv.JsonSchemaValidator;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import java.net.URL;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
import com.sap.cloud.sdk.testutil.MockUtil;
import static io.restassured.RestAssured.when;
@RunWith(Arquillian.class)
public class BusinessPartnerServletTest {
private static final MockUtil mockUtil = new MockUtil();
private static final Logger logger = CloudLoggerFactory.getLogger(BusinessPartnerServletTest.class);
@ArquillianResource
private URL baseUrl;
@Deployment
public static WebArchive createDeployment() {
return TestUtil.createDeployment(BusinessPartnerServlet.class);
}
@BeforeClass
public static void beforeClass() {
mockUtil.mockDefaults();
mockUtil.mockErpDestination();
}
@Before
public void before() {
RestAssured.baseURI = baseUrl.toExternalForm();
}
@Test
public void testService() {
// JSON schema validation from resource definition
final JsonSchemaValidator jsonValidator = JsonSchemaValidator
.matchesJsonSchemaInClasspath("businesspartners-schema.json");
// HTTP GET response OK, JSON header and valid schema
when()
.get("/businesspartners")
.then()
.statusCode(200)
.contentType(ContentType.JSON)
.body(jsonValidator);
}
}
What you see here in the test method testService
, is the usage of RestAssured on a JSON service backend. The HTTP GET request is run on the local route /businesspartners
, the result is validated on multiple assertions:
- HTTP response status code: 200 (OK)
- HTTP ContentType: application/json
- HTTP body is valid JSON code, checked with a
businesspartners-schema.json
definition
New: JSON Schema for servlet response validation
Inside the integration-tests
project, create a new resource file
./integration-tests/src/test/resources/businesspartners-schema.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Business Partner List",
"type": "array",
"items": {
"title": "Business Partner",
"type": "object",
"required": ["BusinessPartner", "LastName"]
},
"minItems": 1
}
As you can see, the properties BusinessPartner
and LastName
will be marked as requirement for every entry of the expected business partner list. The JSON validator would break the test if any of the items was missing a required value.
New: systems.json and credentials
If you run your application on SAP Cloud Platform, the SDK can simply read the ERP destinations from the destination service. However, since the tests should run locally, we need a way to supply our tests with an ERP destination.
Luckily, the SDK provides a utility class for such purposes – MockUtil. This class allows us to mock the ERP destinations we’d typically find on CloudFoundry. To provide MockUtil with the necessary information, you’ll need to add a systems.json or systems.yml file to your test resources directory. MockUtil will read these files and provide your tests with the ERP destinations accordingly. Adapt the URL
as before.
./integration-tests/src/test/resources/systems.json
{
"erp": {
"default": "ERP_TEST_SYSTEM",
"systems": [
{
"alias": "ERP_TEST_SYSTEM",
"uri": "https://URL"
}
]
}
}
That’s it! You can now start all tests with the default Maven command:
mvn test -Derp.username=USER -Derp.password=PASSWORD
Please change the values USER
and PASSWORD
accordingly. If you do not want to pass the erp username and password, checkout the appendix below for an alternative.
If you want to run the tests without Maven, please remember to also use include the command line parameters.
In this blog post, we have explained the virtues of the Virtual Data Model and demonstrated how easy it is to connect to SAP S/4HANA using the SAP Cloud SDK, how to deploy the application including destination configuration, and how to create integration tests.
See the next tutorial in the series here: Step 5 with SAP Cloud SDK: Resilience with Hystrix.
Appendix
Supplying credentials as a file: credentials.yml
Hint: How to remember ERP username and password
If you do not want to pass the erp username and password all the time when executing tests or want to execute tests on a continuous delivery pipeline where more people could see the password in log outputs, you can also provide credentials in a credentials.yml file that the SDK understands.
To do this, create the following credentials.yml file in a save location (e.g., like storing your ssh keys in ~/.ssh), i.e., not in the source code repository.
/secure/local/path/credentials.yml
---
credentials:
- alias: "ERP_TEST_SYSTEM"
username: "user"
password: "pass"
Afterwards you may pass the credentials file as follows when running tests. Make sure to use the absolute path to the file:
mvn test -Dtest.credentials=/secure/local/path/credentials.yml
Troubleshooting
In case you are trying to connect to an OData service endpoint on a server without verifiable SSL certificate, you might see the following error message due to an untrustworthy signature:
Failed to execute GET https://<URL>/$metadata
- To manually override the chain of trust, you can set a special flag on the destination configuration. To avoid any further issues with untrusted certificates in your local Neo deployment environment, please change the
TrustAll
flag in your destinations configuration file./config_master/service.destinations/destinations/ErpQueryEndpoint
... TrustAll=TRUE ...
- If you are running into the same problem in a Cloud Foundry deployment environment and you are using the environment variable approach, please adapt the
destinations
environment variable to additionally include the properties map:[{name: "ErpQueryEndpoint", url: "https://URL", username: "USER", password: "PASSWORD", properties: [{key: "TrustAll", value: "true"}]}]
- If you are using the destination service on Cloud Foundry, add a new additional property to your destination in the Cloud Platform cockpit. Enter TrustAll into the first input (dropdown) field and TRUE into the second field.
If you are still facing problems when connecting to the OData service, try the following to get more insights into what is happening and what can be logged:
- Add a logger implementation to the test artifact’s dependencies in order to get more detailed log output during tests: expand the dependencies section of
integration-tests/pom.xml
with:<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> <scope>test</scope> </dependency>
If you are behind a proxy and want to connect your app running locally with the Cloud Foundry archetype to an SAP S/4HANA system in your network, you can supply your proxy information as part of the destinations environment variable (see Javadoc):
[{name: "ErpQueryEndpoint", url: "https://URL", username: "USER", password: "PASSWORD", properties: [{key: "TrustAll", value: "true"},{key: "proxyHost", value: "my-proxy.com"},{key: "proxyPort", value: "8080"}]}]
Hey Alexander,
first of all: great example on how to use the SDK.
One question from my side: is there anything more to do to establish the ERP connection when deploying to CloudFoundry? I always receive an UnknownHostException that the name or service is not known.
Thanks and best regards
Julian
Hi Julian,
this depends a little bit on the setup you intent to use. We have added a small little prerequisite section that explains which configurations are currently available. To which system do you try to talk to? Is it an S/4HANA Cloud system? Or do you try against an S/4HANA on-prem system. Also it matters whether you try to do it from Neo or CloudFoundry (but see yourself in the updated prerequisite section).
Don't mind to drop us additional questions.
Best regards
Philipp
Did you already manage to run the example on Cloud Foundry with the new destination service against an onPremise system? Any specific troubleshooting hints in that case?
I get the service running, the integration test executes fine in a local environment but despite a destination service and cloud connector setup that does not show obvious issues I end up with an exception.
Hi Thomas,
could you please share some more details on the exception?
It would be great if you could find the time to also post the issue on StackOverflow using the tag "s4sdk" so that others who might have a similar issue can also benefit from your question!
Thank you!
Sander
Hi Thomas,
can you pls share all the relevant details with us, for instance, which exception and what is the stack trace, the message etc.?
Thanks
Marco
I'll do so. Give me some time to reproduce.
Hi Thomas,
just fyi: Have you tried Katja's deep dive on how to use connectivity service with onprem here: https://blogs.sap.com/2018/01/19/deep-dive-7-with-sap-s4hana-cloud-sdk-s4hana-connectivity-made-simple/ ?
Please also bear in mind that at this time, the connectivity service is still in beta despite being already supported by the SDK.
Best regards
Philipp
Hey Alexander,
Very good tutorial, give us many valuable information. We have a similar scenario that we need to call an Odata service provided by S4/HANA cloud from our Application which is deployed on SCP CF. I have two questions related to this scenario,
1.How can we adapt this tutorial to support multi-tenant?
2.If we want to query the Odata service directly from UI, are we able to do that? We are thinking about directly consuming Destination service provided by SCP CF, user can configure tenant-level destinations through Cockpit, but it looks like Destination service is still at Beat version on SCP CF.
Could you kindly share us some ideas? Thank you in advance.
BRs,
yangyang
Hi Yangyang,
regarding the secure setup of a multi-tenant application on CF, please have a look at our tutorial on this topic:
https://blogs.sap.com/2017/07/18/step-7-with-sap-s4hana-cloud-sdk-secure-your-application-on-sap-cloud-platform-cloudfoundry/
You are right, at the moment, the destination service on CF is still in Beta. As long as this is the case, you could rely on the Neo environment to consume a multi-tenant destination. In addition, please consider the option to also expose an OData V4 service using the SAP Cloud Platform SDK for service development. A tutorial on this topic can be found here:
https://blogs.sap.com/2017/09/11/creating-odata-v4-services-using-sap-cloud-platform-sdk-for-service-development/
Best regards
Sander
Hi Alexander,
thank you for the great blog.
We had some problems with calling the OData Service. We wanted to call the cost centers service from our local S/4 HANA and got the following error:
As the service-side certificate is not signed from any root CA, hence, is not trusted (if you call the service in browser you get a warning).
To avoid any issues with untrusted certificates you may set the property TrustAll=TRUE in the created destination property in following location of your project:
With that configuration it works fine for us in Neo.
Best regards,
Bastian
Hey Bastian,
thank you very much for your feedback. Finding out about the TrustAll flag was a good catch! I changed the blog post to also include your solution, see Troubleshooting.
Best regards,
Alexander
Hi Alexander,
I am using a S4HANA OP system which is connected via the SAP Cloud Connector and then exposed via the destination ErpQueryEndpoint as described.
I am able to leverage this destination and create a project in WebIDE which perfectly fetches the service data.
But it dos not work with the SDK as given in this blog and I get an error "Failed to execute OData Metadata request."
I tried the suggestion mentioned in your troubleshooting section and placed TrustAll=TRUE. Thus the local deployment works fine. But SAP CP (neo a well as CF) do not allow me to set this property in the destination and give an error when i try to save, saying "For destinations with HTTPS URL and ProxyType set to 'OnPremise', you are not allowed to add property TrustAll."
Do you have a suggestion as to how I can overcome this issue?
Vikas
@Sander Wozniak :
please help here.. we are facing similar issue.
Hi Alexander,
Thanks for such a great blog. I tried the steps mentioned here - deploying the app locally and accessing the data at localhost:8080. I am able to see the expected JSON data. But when I am trying to access the endpoint to display the JSON data after deploying the app to Neo environment, it gives me following error.
Could you please help me fixing this issue.
Thanks,
Sankeeth
Hi Sankeerth,
you need to configure the ErpQueryEndpoint destination in Neo using the destination tab of your application. It has to look similar to what Tri has posted below.
Best regards
Philipp
Thanks for the response. I see the result in the webpage like as below.
I also added the destination along with the property TrustAll as TRUE. But it didn't help.
I am facing this issue only in neo environment but not in cloud foundry. Can you help me with this?
Hi Sankeerth,
In case a metadata file is either too big (thus taking long to load) or non-existing, then please consider disabling the look up altogether:
By using the "withoutMetadata()" modifier, the meta information about data types will not be loaded. As consequence some special (de)serialization of unusual attribute types may not work as expected.
Best regards
Alex
Hi Alexander,
I'm using Northwind as oData service.
It works perfectly when running local but when I deploy to Cloud Neo, it displays error on browser:
Failed to execute GET http://services.odata.org/V2/Northwind/Northwind.svc/$metadata.
I've set destination as ErpQueryEndpoint
Could you please help me?
Thanks
Tri
Hi Tre,
as written in the blog, please try setting the TrustAll property to TRUE. In the destination service this can be done via additional properties you see in your screenshot.
Best regards
Philipp
Hi Philipp,
I've tried to set TrustAll property but it doesn't allow me to do it.
Please try to use https:// as protocol, TrustAll indeed does not make much sense on plain http.
Hi Philipp,
Thanks for your effort.
This is error when i check connection.
Even though I can save it successfully, the result is
I've checked the log:
Have you tried this successfully on Neo, Philipp?
Thanks in advance.
Tri
Hi,
I have the same problem. I configured a S/4Hana Cloud destination but I have the "Failed to execute GET $metadata" error. The same application running locally is instead able to call the destination. Furthermore I can run a simple Fiori app that can communicate with this destination.
I have tried both the .withoutMetadata() on ODataQueryBuilder than the TrustAll option.
Any suggestion?
Hello Francesco,
are you running this in the Neo environment in a trial account? (URL contains hanatrial)
If yes, you may need to manually configure a proxy (this is not necessary elsewhere, only do this for the trial region of Neo)
Add the following Additional Properties to your destination (click New Property and type this into the field - do not use the dropdown options):
Best,
Henning
Yes, I'm running on trial account. Using the properties you suggested, I solved the problem. Thanks
Hi Henning,
I have same issue but I am using Canary account for CF and have a productive Neo account.
Vikas
Hello Vikas,
can you describe your setup and the error condition that you are seeing in more detail? Which version of the SAP S/4HANA Cloud SDK are you using?
Best regards,
Henning
Change log (December 22, 2017):
Change log (January 04, 2018):
Hi Hennig
Can you also provide an example for filtering the manual way to OData. We need a ComplexFilterExpression to filter on 3 fields.
Please explain also the OR and AND example.
Thanks,
Robert
Hello Robert,
with the manual way, the filter would look similar to the following:
AND would simply work by calling the same method multiple times.
We plan to describe more complex filter expressions in the future. If you need it now: they are available for the manual approach if you manage the dependency of com.sap.cloud.servicesdk:odatav2-connectivity to version 1.11.4 (add this as first dependency into the dependency management section of the pom.xml in the root folder).
Best regards,
Henning
Hi Alexander,
This blog is awesome :). Thank you.
Just have one question. The name for backend Destination is mentioned as "ErpQueryEndpoint". is this mandatory that the destination name has to be always this name?
Thank you and Best Regards,
Venu
Dear Venu,
You cannot change the default destination name. But you can use your very own:
Please keep in mind, to update your local / SCP destination configuration accordingly.
Best regards
Alexander
Hi Alexander,
I tried this step 4 for the second time but I always get the message “Internal Server Error” when running https://MY-ROUTE/businesspartners.
A colleague has the same issue.
I use the URL https://erpqw9a74d7a9d1.hana.ondemand.com and when I run the integration test “BusinessPartnerServiceTest.java” I get a success message.
Could you please help me?
Thank you.
Best regards,
Martin
Hi Martin,
it might be that you are using a system which is not reachable from the landscape that you are using.
Could you please share some more details on the exception in the log file that you get when running the application?
In case you find the time, it would also be great if you could post your question to StackOverflow using the tag "s4sdk" so that others who might have the same or a similar issue may benefit from it as well in the future!
Thank you!
Sander
A result of the further discussion with Sander and Henning Heitkoetter was that the "SAP Specifics" (https://wiki.wdf.sap.corp/wiki/display/RAApps/Tutorials%3A+SAP+Specifics) for Step 4 were adapted:
The internal recommendation is now to use S/4HANA VLAB system E1Y.
Hello Martin, Did u able resolve this error? I am also getting similar Error "
Internal Server Error"
Thanks
Hello,
I would be really thankfull, if you could give me some help.
I'm working the example for "manual way of OData" for BusinessPartner and I have some troubles with the URL in :
Can you give me the ErpEndPoint URL for access to A_BusinessPartner ?
Hello Temjanika,
you need to supply the URL and credentials to an SAP S/4HANA system that you have access to. There is no public sandbox system or similar for this purpose, so I cannot provide you with an URL.
Hello Henning,
Thank you, I solved that issue, now I am working on /sap/opu/odata/iwbep/GWSAMPLE_BASIC, and I have error when I want to get the BusinessPartners, like here:
final List<BusinessPartnerType> bpartners = ODataQueryBuilder
.withEntity("/sap/opu/odata/iwbep/GWSAMPLE_BASIC/", "BusinessPartnerSet" )
.select("BusinessPartnerID",
"CompanyName")
.errorHandler(new ODataV2SimpleErrorHandler())
.build()
.execute(endpoint)
.asList(BusinessPartnerType.class) .
It doesn't work. I did by following your steps, and no chance.
But it works like a charm for ProductSet, ClientSet, SalesOrderSet from /sap/opu/odata/iwbep/GWSAMPLE_BASIC .
My error is: It can't parse the metadata.
Thank you for any help.
All the best !
In addition to this, I tested my code (with servlets for SalesOrderSet, SalesOrderItemLineSet, ProductSet, ContactSet, BusinessPartnerSet) with the Endpoint:
Name=ErpQueryEndpoint
URL=https://sapes5.sapdevcenter.com
TrustAll=TRUE
Type=HTTP
Password=####
Authentication=BasicAuthentication
User=P##########
sap-client=002
(for ex. to see the sales order on Internet -> https://sapes5.sapdevcenter.com + /sap/opu/odata/iwbep/GWSAMPLE_BASIC/ + SalesOrderSet ) ,
AND:
On local with localhost:8080/firstapp-application, and on SCP Neo it worked very well for all routes (/products, /salesorders, /contacts, ...) but when I run for BusinessPartners I got an error 500, and when I checked the log the error was that it couldn't parse the metadata. I think that there is a problem ;
After that I created a destination on-premise in my SCP cockpit pointing to my ABAP machine cause I found the transaction /sap/opu/odata/IWBEP/GWSAMPLE_BASIC that is the same as the GWSAMPLE_BASIC at sapes5 (http://prntscr.com/j3adap ) . Then I run again the project, and the results were the same as for sapes5, it worked for /products, /salesorder, /salesorderlineitem, /contacts, but for /businesspartners the error was with parsing the metadata (http://prntscr.com/j3agrf ) .
Thank you in advance for any help!
All the best!
Hi, Nnikamet Anne.
Excuse me, could you give me your project as an example to serve as a guide in my project?
I have problems with the integration with NEO, with the following error:
com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationNotFoundException: No destination for name ‘SAP_Gateway’ could be found in any of the registered loaders.
CONFIG DESTINATION IN NEO :
JAVA SPRING BOOT CODE:
If the metadata cannot be read for a given OData endpoint / entity, we recommend to add the modifier "withoutMetadata" to the ODataQueryBuilder, e.g.
Very strange, that metadata of ProductSet, ClientSet and SalesOrderSet from the same OData endpoint can be read without issues, whereas BusinessPartnerSet fails. Is it possible to forward the metadata file to Henning or me? Maybe this can be fixed in the future.
Best regards
Alexander
Hello Alexander, hello Henning,
I am trying to use the Cloud Foundry destination service (beta) in order to call a OnPrem S/4 Hana System. My code works pretty fine using the SAP Gateway - Demo System (ES5). However, once I switch the destination to "OnPremise" and changing the url of course, it doesn't work anymore. The SCC seems to be configured correctly.
The code in this sample https://github.com/SAP/cloud-cf-product-list-sample/tree/master/exercises/10_connectivity uses a ConnectivityConsumer. Do I need to use the connectivity service as well or is this covered by S4SDK?
Best regards
Oliver
Hello Oliver,
you would need to additionally create a service instance of the connectivity service and bind it to the application (e.g., add my-connectivity to services section in manifest.yml).
Everything else is handled by the SAP S/4HANA Cloud SDK.
Best regards,
Henning
Hello Oliver,
Additional libaries and classes such as ConnectivityConsumer are not required. But for connecting to OnPremise systems you are indeed required to bind an instance of connectivity service to the application on Cloud Foundry.
An elaborate description of your use-case and the tutorial can be found in Deep Dive 7 – Connectivity – Made Simple.
Best regards
Alexander
Hello Alexander, hello Henning,
Thank you guys for your reply. I have created and bind the connectivity service and followed the instructions of tutorial Deep Dive 7 (setting up SCC and the destination, as well as bind the app to the destination and uaa service).
During runtime, I receive the following message errror:
It seems, that the cloud connector doesn't get any request:
Any ideas?
Best regards
Oliver
Hey Oliver,
Can you please elaborate on the exceptions being thrown, e.g. “Error occurred while populating metadata” and “Fallback called because of exception“. You can download the full log file with the button on the upper right of the log screen. There should be some hints on “caused-by” exceptions.
There are various things which may prevent an application connecting to the OnPremise system. Please test the connectivity in the destinations overview screen on Cloud Foundry Cockpit. There should be a button to “check availability of destination connection“. Does pressing this button yield any additional information?
Best regards
Alexander
Hello Alexander,
Thank you for replying.
Regarding Connectivity: The function “check availability of destination connection“ is missing in Cloud Foundry Trial. I assume from Neo that it should be next to the download button, but it isn't there.
This is the relevant part of the log. Unfortunately it does not give any hint that brings me further:
2018-04-12T11:41:09.042+0000 [APP/PROC/WEB/0] OUT 2018-04-12 11:41:09.042 INFO 7 --- [nio-8080-exec-6] c.x.v.c.BusinessPartnerController : endpoint: GET /businesspartners called, handled by Method getBusinessPartners of class BusinessPartnerController
2018-04-12T11:41:09.043+0000 [APP/PROC/WEB/0] OUT 2018-04-12 11:41:09.043 INFO 7 --- [nio-8080-exec-6] c.s.c.s.s.connectivity.ErpConfigContext : Falling back to locale "de_DE". To specify the locale, set the property on destination "ErpQueryEndpoint" or provide the locale as explicit argument. (END OF LOG ENTRY)
2018-04-12T11:41:09.046+0000 [APP/PROC/WEB/0] OUT 2018-04-12 11:41:09.045 INFO 7 --- [Command#t=#u=-2] c.s.c.s.s.connectivity.ErpConfigContext : Falling back to locale "de_DE". To specify the locale, set the property on destination "ErpQueryEndpoint" or provide the locale as explicit argument. (END OF LOG ENTRY)
2018-04-12T11:41:09.196+0000 [RTR/6] OUT <appname>.cfapps.eu10.hana.ondemand.com - [2018-04-12T11:41:09.183+0000] "GET /favicon.ico HTTP/1.1" 200 0 946 "https://approuter-<...>.cfapps.eu10.hana.ondemand.com/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "10.0.136.2:53994" "10.0.137.100:61077" x_forwarded_for:"217.255.165.122, 10.0.136.3, 52.28.241.88, 10.0.136.2" x_forwarded_proto:"https" vcap_request_id:"fdd77a61-4b1b-4b50-4a17-04eea3204fd6" response_time:0.01222125 app_id:"b0e6861a-e7f5-4f58-aa0a-3f52f3a7b1df" app_index:"0" x_b3_traceid:"181ee50b58e2e789" x_b3_spanid:"181ee50b58e2e789" x_b3_parentspanid:"-"
2018-04-12T11:41:19.033+0000 [RTR/6] OUT <appname>.cfapps.eu10.hana.ondemand.com - [2018-04-12T11:41:09.020+0000] "GET /businesspartners HTTP/1.1" 200 0 1516 "https://approuter-<...>.cfapps.eu10.hana.ondemand.com/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "10.0.72.5:60668" "10.0.137.100:61077" x_forwarded_for:"217.255.165.122, 10.0.72.0, 52.28.241.88, 10.0.72.5" x_forwarded_proto:"https" vcap_request_id:"382b66a3-e8dc-4199-692e-7ec0bdf4cccf" response_time:10.013440161 app_id:"b0e6861a-e7f5-4f58-aa0a-3f52f3a7b1df" app_index:"0" x_b3_traceid:"e4dd53b2bc2452c6" x_b3_spanid:"e4dd53b2bc2452c6" x_b3_parentspanid:"-"
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT 2018-04-12 11:41:19.045 WARN 7 --- [ HystrixTimer-4] c.x.v.command.BusinessPartnerErpCommand : Fallback called because of exception:
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT com.netflix.hystrix.exception.HystrixTimeoutException: null
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1$1.run(AbstractCommand.java:1154) [hystrix-core-1.5.12.jar!/:1.5.12]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:45) [hystrix-core-1.5.12.jar!/:1.5.12]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41) [hystrix-core-1.5.12.jar!/:1.5.12]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:61) [hystrix-core-1.5.12.jar!/:1.5.12]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.tick(AbstractCommand.java:1159) [hystrix-core-1.5.12.jar!/:1.5.12]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99) [hystrix-core-1.5.12.jar!/:1.5.12]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_141]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_141]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_141]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_141]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_141]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_141]
2018-04-12T11:41:19.046+0000 [APP/PROC/WEB/0] OUT at java.lang.Thread.run(Thread.java:748) [na:1.8.0_141]
2018-04-12T11:41:19.294+0000 [APP/PROC/WEB/0] OUT 2018-04-12 11:41:19.294 ERROR 7 --- [Command#t=#u=-2] c.s.c.s.o.c.c.m.GuavaMetadataCache : Error occurred during populating metadata : com.sap.cloud.sdk.s4hana.datamodel.odata.helper.ODataVdmErrorResultHandler$ErpODataException:
Best regards
Oliver
Hi Expert.
Once i Publish Odata service from S/4 HANA Public cloud using communication arrangement to SAP cloud platform. I can consume this service very well from SAP UI5/Fiori using SCP.
Now what is value addition, i will get if i will use S/4 hana SDK from JAVA program instead of using SAP UI5/ Fiori?
Thanks.
The SAP S/4HANA Cloud SDK is especially useful in case you add additional business functionalities instead of just forwarding the data. Especially in SAP S/4HANA Cloud there are only limited possibilities to build extensions and implemented additional functionality directly in S/4HANA (see In-App Extensibility).
Thus, the SAP Cloud Platform offers the possibility to implement these extensions and deploy them as independent cloud-native applications.
It also offers you a simple mechanism to offer you extensions to a wide range of customers, if it is built as multi tenant application.
Hi Expert,
When i am trying this blog with Neo, i am getting error "Failed to execute OData Metadata request" and when i am trying with cloud foundry then i am getting error " Internal Server Error" .
Please guide me, how can i overcome these errors.
Is it happening due to S/4 hana Public cloud server? But O data service URL is working well with Postman.
thanks
Hi Expert,
I could able to resolve issue in cloud foundry, but not on NEO
I was missing on 3 things
Thanks
Hello Vipin,
Glad to hear that you were able to solve the issue on Cloud Foundry (actually, only the service binding is related to Cloud Foundry, the other two items you mentioned are only relevant when running the tests locally).
Regarding neo: are you running this in the Neo environment in a trial account? (URL contains hanatrial)
If yes, you may need to manually configure a proxy (this is not necessary elsewhere, only do this for the trial region of Neo)
Add the following Additional Properties to your destination (click New Property and type this into the field – do not use the dropdown options):
Hope this helps. Otherwise, please send your logs or more details on error messages.
Best regards,
Henning
Thanks a lot Henning, I will try your suggestion in NEO.
I want to ask you one more question.
Let us say via in app extension, if we have added new custom field on Business partner in S/4 hana Public cloud.
Now, will Odata service which we are consuming via business API hub will get also extended?
if yes, then how S4 HANA SDK will come to know about this new custom Field? I am trying to mix in app extension with S4 HANA SDK.
Yes, the OData service will contain the custom field if you enable the usage of your custom field in the OData API in SAP S/4HANA Cloud, using the custom fields key user tool.
Please see the following blog post on how you can consume custom fields in the SAP S/4HANA Cloud SDK: https://blogs.sap.com/2018/01/02/step-22-with-the-sap-s4hana-cloud-sdk-extensibility-type-safe-expand-and-dependency-injection-with-the-virtual-data-model-for-odata/
Hi,
Thanks for your dedicated tutorial. I successfully deploy the hello world app to SCP based on CF approach, but in this tutorial, I would like to test an internal SAP S/4 Cloud System connectivity as I am an internal SAP developer, is there any information or wiki that can be consumed, aka the test system client I can use and etc, thanks for your attention.
Best Regards,
Guoquan
Hallo Guoquan,
Please find the documentation on how to establish connectivity between SCP and internal systems: S/4HANA Connectivity – Made Simple
You are going to secure the application with XSUAA and add Destination and Connectivity service bindings. For OnPremise systems you have to configure a CloudConnector as well.
Best regards
Alexander
Dear Alexander,
I'm trying to follow your blogpost and use OData to query an SAP System I have access to.
For the ErpQueryEndpoint URL I'm using: https://host:port
but when I try to use DefaultBusinessPartnerService to list Business Partners I'm getting the following error:
Could you help me out? I think it might be something missing in the URL. Is there anything I have to add besides host and port number?
Thanks,
Cássio
Hello Cássio,
have you tried to connect to the OData endpoint by browser or Postman? In case the very same error message shows up, I would assume the OData endpoint is not enabled / exposed on your SAP system.
Please take a look into the following short tutorial about enabling OData APIs: https://blogs.sap.com/2017/09/15/step-12-with-sap-s4hana-cloud-sdk-consuming-business-api-from-s4hana-via-odata/
I hope this helps.
Best regards,
Alexander
Hi Alexander,
I am have following the blog after the successful deployment for 3rd one. I am able to deploy the BusinessPartnerServlet on CF but when I am trying to access it through URL I am getting internal error.
To create the communication arrangement I have flowed this blog
https://blogs.sap.com/2017/09/15/step-12-with-sap-s4hana-cloud-sdk-consuming-business-api-from-s4hana-via-odata/
Could you please help us to know where I can trace this or any destination I have missed in mainfest ,credential file which I have added into project.
Regards,
Dear Amit,
kindly note that deploying the servlet to SAP Cloud Platform and creating the communication arrangement in SAP S/4HANA Cloud are, from a general perspective, independent from each other.
Therefore, let us focus on deploying and accessing your servlet firstly.
Kindly share the internal error with us.
We recommend to start with a simple and clean servlet printing Hello World. Once you can access that servlet running in SAP Cloud Platform, you can go ahead adding the connection to SAP S/4HANA Cloud.
Kind regards
Marco Dahms
Hi Macro,
I have removed that.
I am able to deploy successfully however when I am checking the CF trial version I am facing the issue while calling business partners servlet and getting internal error. please find the attached error screen shot and project which I have created.
Regards

Hi Amit,
can you kindly share the internal stack trace with us? I can be found in the output of the "cf logs --recent firstapp" command.
Greetings
Chris
HI Chris,
Please find the below logs
C:\Users\amit kulkarni\firstapp>cf logs --recent firstapp
Retrieving logs for app firstapp in org S0019145314trial_trial / space dev as amit.c.kulkarni@.com...
2018-07-19T12:25:13.61+0530 [CELL/0] OUT Cell 4ae79ad3-8787-4aed-9200-43b839001833 requesting replacement for instance 5e61d757-4760-471f-439e-eee9
2018-07-19T12:25:14.17+0530 [CELL/0] OUT Cell 2b140215-60d2-4ac0-af14-b842521c5ef9 creating container for instance abb23b39-8a6a-4d1f-6ad2-6780
2018-07-19T12:25:14.40+0530 [CELL/0] OUT Cell 2b140215-60d2-4ac0-af14-b842521c5ef9 successfully created container for instance abb23b39-8a6a-4d1f-6ad2-6780
2018-07-19T12:25:18.21+0530 [CELL/0] OUT Starting health monitoring of container
2018-07-19T12:25:20.90+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:20.885Z","written_ts":1202649896207235,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"/System/AuditLog","thread":"main","level":"ERROR","categories":[],"msg":"Cannot send audit log message to the backend: audit log service environment configuration is missing or incomplete." }
2018-07-19T12:25:20.91+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:20.918Z","written_ts":1202649926726658,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"/System/AuditLog","thread":"main","level":"ERROR","categories":[],"msg":"Cannot send audit log message to the backend: audit log service environment configuration is missing or incomplete." }
2018-07-19T12:25:21.38+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:21.379Z","written_ts":1202650388243558,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"org.apache.catalina.startup.Catalina","thread":"main","level":"INFO","categories":[],"msg":"Initialization processed in 2521 ms" }
2018-07-19T12:25:21.39+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:21.388Z","written_ts":1202650398484554,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"com.sap.xs.logging.catalina.LoggingLevelChangeListener","thread":"main","level":"INFO","categories":[],"msg":"Logging level configuration" }
2018-07-19T12:25:21.46+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:21.462Z","written_ts":1202650470817267,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"com.sap.xs.logging.catalina.LoggingLevelChangeListener","thread":"main","level":"INFO","categories":[],"msg":"Logging level changed. Location: ROOT changed level from ERROR to INFO. " }
2018-07-19T12:25:21.46+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:21.468Z","written_ts":1202650477028113,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"/System/AuditLog","thread":"main","level":"ERROR","categories":[],"msg":"Cannot send audit log message to the backend: audit log service environment configuration is missing or incomplete." }
2018-07-19T12:25:21.53+0530 [APP/PROC/WEB/0] OUT audit/configuration-changes: {"uuid":"11fcfb2b-2302-4e3d-b244-9fca99010663","user":"xsa_java_internal","time":"2018-07-19T06:55:21.476Z","success":true,"object":{"type":"com.sap.xs.java.log.location","id":{"name":"ROOT","severity":"ERROR"}},"attributes":[{"name":"severity","old":"ERROR","new":"INFO"}],"status":"END"}
2018-07-19T12:25:21.53+0530 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-19T06:55:21.534Z","written_ts":1202650543109172,"component_type":"application","component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","space_name":"dev","component_name":"firstapp","component_instance":"0","organization_id":"-","correlation_id":"-","organization_name":"-","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","container_id":"10.0.73.61","type":"log","logger":"com.sap.xs.logging.catalina.LoggingLevelChangeListener","thread":"main","level":"INFO","categories":[],"msg":"Logging level changed. Location: com.sap.cloud.sdk changed level from null to INFO. " }
Hi Amit,
okay, I cannot see any reason for the internal server error. Can you please execute the following steps:
Greetings
Chris
Hi Chris,
Thanks for your response please find the below logs I am not able to attach the log file or paste it in this thread
m.google.common.cache.LocalCache$Segment.get(LocalCache.java:2044)","\tat com.google.common.cache.LocalCache.get(LocalCache.java:3951)","\tat com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4870)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationFacade.getGenericDestinationsByName(ScpCfDestinationFacade.java:162)","\t... 48 more","Caused by: java.util.concurrent.ExecutionException: Observable onError","\tat rx.internal.operators.BlockingOperatorToFuture$2.getValue(BlockingOperatorToFuture.java:118)","\tat rx.internal.operators.BlockingOperatorToFuture$2.get(BlockingOperatorToFuture.java:102)","\tat com.netflix.hystrix.HystrixCommand$4.get(HystrixCommand.java:423)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.ScpCfDestinationFacade.lambda$getGenericDestinationsByName$0(ScpCfDestinationFacade.java:168)","\tat com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4875)","\tat com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)","\tat com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2276)","\t... 53 more","Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand#t=#u= failed and fallback disabled.","\tat com.netflix.hystrix.AbstractCommand.handleFallbackDisabledByEmittingError(AbstractCommand.java:1052)","\tat com.netflix.hystrix.AbstractCommand.getFallbackOrThrowException(AbstractCommand.java:878)","\tat com.netflix.hystrix.AbstractCommand.handleFailureViaFallback(AbstractCommand.java:1034)","\tat com.netflix.hystrix.AbstractCommand.access$700(AbstractCommand.java:60)","\tat com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:622)","\tat com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:601)","\tat rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)","\tat rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)","\tat rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)","\tat com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.onError(AbstractCommand.java:1194)","\tat rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.onError(OperatorSubscribeOn.java:80)","\tat rx.observers.Subscribers$5.onError(Subscribers.java:230)","\tat rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)","\tat rx.observers.Subscribers$5.onError(Subscribers.java:230)","\tat com.netflix.hystrix.AbstractCommand$DeprecatedOnRunHookApplication$1.onError(AbstractCommand.java:1431)","\tat com.netflix.hystrix.AbstractCommand$ExecutionHookApplication$1.onError(AbstractCommand.java:1362)","\tat rx.observers.Subscribers$5.onError(Subscribers.java:230)","\tat rx.observers.Subscribers$5.onError(Subscribers.java:230)","\tat rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44)","\tat rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28)","\tat rx.Observable.unsafeSubscribe(Observable.java:10256)","\tat rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)","\tat rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)","\tat rx.Observable.unsafeSubscribe(Observable.java:10256)","\tat rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)","\tat rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)","\tat rx.Observable.unsafeSubscribe(Observable.java:10256)","\tat rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)","\tat rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)","\tat rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)","\tat rx.Observable.unsafeSubscribe(Observable.java:10256)","\tat rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)","\tat com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:56)","\tat com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:47)","\tat com.sap.xs.threadlocal.hystrix.ThreadLocalCallable.call(ThreadLocalCallable.java:29)","\tat com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.java:69)","\tat rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)","\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)","\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)","\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)","\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)","\t... 1 more","Caused by: com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException: Failed to get access token for destination service.","\tat com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand.getAccessToken(DestinationServiceCommand.java:107)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand.run(DestinationServiceCommand.java:117)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand.run(DestinationServiceCommand.java:26)","\tat com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)","\tat com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)","\tat rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)","\t... 27 more","Caused by: com.sap.cloud.sdk.cloudplatform.connectivity.TokenRequestFailedException: Failed to determine cache key.","\tat com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.getCacheKey(XsuaaService.java:156)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.getServiceToken(XsuaaService.java:166)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.DestinationServiceCommand.getAccessToken(DestinationServiceCommand.java:104)","\t... 32 more","Caused by: com.sap.cloud.sdk.cloudplatform.tenant.exception.TenantNotAvailableException: Failed to get current tenant: tenant not available. For details on the security configuration, please refer to the SAP Cloud Platform documentation. Tutorials on the configuration are available at \"https://help.sap.com/viewer/p/SAP_S4HANA_CLOUD_SDK\".","\tat com.sap.cloud.sdk.cloudplatform.tenant.AbstractTenantFacade.getCurrentTenant(AbstractTenantFacade.java:138)","\tat com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor.getCurrentTenant(TenantAccessor.java:73)","\tat com.sap.cloud.sdk.cloudplatform.cache.CacheKey.ofTenantIsolation(CacheKey.java:164)","\tat com.sap.cloud.sdk.cloudplatform.connectivity.XsuaaService.getCacheKey(XsuaaService.java:148)","\t... 34 more"] }
2018-07-19T17:11:46.32+0530 [RTR/3] OUT firstapp-fearless-nyala.cfapps.eu10.hana.ondemand.com - [2018-07-19T11:41:45.826+0000] "GET /businesspartners HTTP/1.1" 500 0 106 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36" "-" "10.0.137.56:62199" x_forwarded_for:"-" x_forwarded_proto:"https" vcap_request_id:"a3ab1f67-afa2-40e1-736e-57797389d99a" response_time:0.497720278 app_id:"7facee61-779e-4cd9-8e97-bfff4cd0c3b8" app_index:"0" x_b3_traceid:"ac95750c08477e00" x_b3_spanid:"ac95750c08477e00" x_b3_parentspanid:"-"
2018-07-19T17:11:46.32+0530 [RTR/3] OUT
Regards,
Hi Amit,
the problem is that you have no tenant configured. At this point in the tutorial you need to provide the "ALLOW_MOCKED_AUTH_HEADER: true" flag, so that the tenant can be mocked by the SDK for you.
Please refer to the "Subscribe to Services" section, therein right below the manifest.yml. There we described how you set the flag and why it is necessary.
Greetings
Chris
hi chris,
I have activated both services please find the attached screen shot mainfest.yml file.
Regards,
Hi Amit,
as mentioned above: can you please add the entry "ALLOW_MOCKED_AUTH_HEADER: true" right below your "SET_LOGGING_LEVEL: ..." entry. This allows the SDK to mock your tenant.
See the blog post for more details, esp. in regards to security implications.
Greetings
Chris
HI Chris,
Thanks for your reply
I made the changes as you pointed after the successful build I got below error
C:\Users\amit\firstapp>cf push
Pushing from manifest to org S0019145314trial_trial / space dev as amit@.com...
Using manifest file C:\Users\amit\firstapp\manifest.yml
yaml: line 12: did not find expected key
FAILED
Also I checked for 2 services
cf create-service xsuaa application my-xsuaa
cf create-service destination lite my-destination
both services are available
C:\Users\amit\firstapp>cf create-service xsuaa application my-xsuaa
Creating service instance my-xsuaa in org S0019145314trial_trial / space dev as amit.@.com...
OK
Service my-xsuaa already exists
C:\Users\amit\firstapp>cf create-service destination lite my-destination
Creating service instance my-destination in org S0019145314trial_trial / space dev as amit.c@.com...
OK
Service my-destination already exists
C:\Users\amit\firstapp>
applications:
- name: firstapp
memory: 768M
random-route: true
path: application/target/firstapp-application.war
buildpack: sap_java_buildpack
env:
TARGET_RUNTIME: tomee
JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:96m..'
SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'
ALLOW_MOCKED_AUTH_HEADER: true
services:
- my-destination
- my-xsuaa
# - my-application-logs
# - my-connectivity
Regards,
Hi Amit,
there seems to be an indentation problem/inconsistency in your manifest.yml. Can you kindly check, that the indentations still look exactly as in your picture above? The "ALLOW_MOCKED_AUTH_HEADER" line should have the same indentation as the "SET_LOGGIN_LEVEL" above it.
If the error still occurs, please provide a picture of the file, as whitespaces are swallowed in the comments.
Greetings
Chris
P.S.: Notes on YAML and indentation: http://yaml.org/spec/1.2/2009-07-21/spec.html#id2576668
HI Chris,
Thanks for help your were correct it is deployed successfully now :). but as per the blog I am trying to deploy business servlet but it is still giving ouput for hello world could you please give your valuable inputs.
Regards,
Hi Amit,
as part of the blog post you added a new Servlet to your project, which now listens to the "businesspartners" endpoint (see the annotation on the new "BusinessPartnerServlet" class). This means you need to adjust your URL to something like https://firstapp-fearless-nyala.cfapps.eu10.hana.ondemand.com/businesspartners.
And as long as you have the "HelloWorldServlet" in your project it will listen to the "hello" enpoint (see the annotation on the "HelloWorldServlet" class).
I hope this reduces the confusion a bit.
Greetings
Chris
Hi Chris,
I am getting meta error while executing business servlet
also I maintained below 2 properties mention by Henning
proxyHost = proxy-trial.od.sap.biz
proxyPort = 8080
below are the logs for same error
2018-07-23T08:35:00.648+0000 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-23T08:35:00.648Z","written_ts":1548718903559208,"component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","component_name":"firstapp","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","Application":"firstapp","container_id":"10.0.137.27","type":"log","logger":"com.sap.cloud.sdk.odatav2.connectivity.ODataQuery","thread":"http-bio-0.0.0.0-8080-exec-7","level":"ERROR","categories":[],"msg":"Successfully connected to destination service." }
2018-07-23T08:35:01.564+0000 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-23T08:35:01.564Z","written_ts":1548719819594615,"component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","component_name":"firstapp","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","Application":"firstapp","container_id":"10.0.137.27","type":"log","logger":"com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache","thread":"http-bio-0.0.0.0-8080-exec-7","level":"ERROR","categories":[],"msg":"Error occurred during populating metadata : org.apache.olingo.odata2.api.ep.EntityProviderException: An exception of type 'WstxUnexpectedCharException' occurred." }
2018-07-23T08:35:01.566+0000 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-23T08:35:01.566Z","written_ts":1548719821444157,"component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","component_name":"firstapp","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","Application":"firstapp","container_id":"10.0.137.27","type":"log","logger":"com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache","thread":"http-bio-0.0.0.0-8080-exec-7","level":"ERROR","categories":[],"msg":"Error occurred during populating metadata : org.apache.olingo.odata2.api.ep.EntityProviderException: An exception of type 'WstxUnexpectedCharException' occurred." }
2018-07-23T08:35:01.568+0000 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-23T08:35:01.567Z","written_ts":1548719823101244,"component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","component_name":"firstapp","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","Application":"firstapp","container_id":"10.0.137.27","type":"log","logger":"com.sap.cloud.sdk.odatav2.connectivity.ODataQuery","thread":"http-bio-0.0.0.0-8080-exec-7","level":"ERROR","categories":[],"msg":"Successfully connected to destination service." }
2018-07-23T08:35:02.102+0000 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-23T08:35:02.101Z","written_ts":1548720357266697,"component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","component_name":"firstapp","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","Application":"firstapp","container_id":"10.0.137.27","type":"log","logger":"com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache","thread":"http-bio-0.0.0.0-8080-exec-7","level":"ERROR","categories":[],"msg":"Error occurred during populating metadata : org.apache.olingo.odata2.api.ep.EntityProviderException: An exception of type 'WstxUnexpectedCharException' occurred." }
2018-07-23T08:35:02.103+0000 [APP/PROC/WEB/0] OUT { "written_at":"2018-07-23T08:35:02.102Z","written_ts":1548720358350596,"component_id":"7facee61-779e-4cd9-8e97-bfff4cd0c3b8","component_name":"firstapp","DCComponent":"","organization_name":"-","component_type":"application","space_name":"dev","component_instance":"0","organization_id":"-","correlation_id":"-","CSNComponent":"","space_id":"e6d39281-d84a-4daa-93ef-7f815f399892","Application":"firstapp","container_id":"10.0.137.27","type":"log","logger":"com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache","thread":"http-bio-0.0.0.0-8080-exec-7","level":"ERROR","categ
Regards,
Hi Amit,
if I see it correctly you are using CloudFoundry and not Neo as your platform, is that assumption right? If so you don't need to provide this proxy, as Henning mentioned in his post.
Therefore, a first fix could be removing this configuration.
If that does not fix it you could try to provide the "TrustAll = TRUE" flag to the destination, as described in the Troubleshooting section of the Blog Post.
If that also does not fix the problem, can you please provide a screenshot of your configuration of the ErpQueryEndpoint destination (without sensitive data)?
Greetings
Chris
Hi Chris,
Thanks for your input I am still getting the meta data error please find the below screens shot for Erp destination I have configure the “TrustAll = TRUE” parameter also. I am able to ping the destination successfully and getting
Connection to "ErpQueryEndpoint" established. Response returned: "302: Redirect"
Could you please confirm if I need to configure Integration Test for BusinessPartnerServlet portion also.
Regards,
Hi Amit,
okay, your destination looks good.
Let's try to get some more information out of your application. Can you please add the logback dependency as described in the troubleshooting section of the guide? This should enhance the log-output and give us a better idea what went wrong.
Another idea to get better/additional information is to run your application locally with "mvn clean install && mvn tomee:run -pl application". When the last line of log output says something along the line of "Server started" you can go to the URL "http://localhost:8080/businesspartners". You can read the "On SAP Cloud Plaform Cloud Foundry" > "Run on a Local Server" section for further information. This starts the server locally and gives more easily readable log output. Can you kindly provide us with the extended log output?
Greetings
Chris
I have a question regarding the destination service in cloud foundry environment, no matter what URL I configured, the "Check Connection" button will always return successfully, it seems ridiculous?
you can see screen shot here:http://www.z4a.net/image/7PKdNr
Hi Guoquan,
good catch! I reported this to the colleagues from the Connectivity Team and they are looking into the issue.
In general this "Check Connection" action just checks (or better should check) the connectivity on a basic level, so just whether the given host is reachable. This call does not contain credentials. Such a more throughout check might be added sometime in the future, but no clear timeline is planned yet.
Greetings
Chris
I can directly access the Odata service configured in destination via postman or browser, however, I do suffer the destination service in CF, which is really a black box and hard to trace issues.
Hi Guoquan,
I understand your issue. The colleagues are looking into improving the Check so that the configuration can be easily verified.
At the same time we have an item in our backlog to investigate how the S/4HANA Cloud SDK might improve its error messages in terms of misconfigured connections. With those it might be easier to trace issues when using the SDK.
Greetings
Chris
Hi,
I am having some trouble configuring destinations in Cloud Foundry.
I am trying to configure the s4hana cloud url in destination at subaccount level. But when I click on check connection it gives an error stating “failed to resolve” . Whereas sandbox and northwind URL seems reachable from cloud foundry.
You can find the screenshot of error here
Are you sure that this URL is available in the public internet? To me it appears that this endpoint is only reachable from within some kind of internal network.
Hi everyone,
Hi Meenakshi,
i'd assume that the destination you've created in your Cloud Foundry subaccount isn't named "
ErpQueryEndpoint" but instead has a typo or something likewise in it.
Best regards,
Martin
Hi, Martin Schenk. I also have the same problem running on NEO.
Error:
On running firstapp>mvn clean install, am getting an error as below:
Failed to execute goal com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:2.13.2:usage-analytics (default) on project firstapp-application: Execution default of goal com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:2.13.2:usage-analytics failed: Plugin com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:2.13.2 or one of its dependencies could not be resolved: Failed to collect dependencies at com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:jar:2.13.2 -> com.sap.cloud.s4hana.plugins:usage-analytics:jar:[2.13.2,): No versions available for com.sap.cloud.s4hana.plugins:usage-analytics:jar:[2.13.2,) within specified range -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <goals> -rf :firstapp-application
I followed the instructions till this step as per the guide. Can you please suggest.
Thanks
Sudarshan
Hi Suarshan,
thanks for your question, but please only ask them once, so that we don’t have to copy our answers all over the place.
Have a look at the answer to your other copy of this question here: https://blogs.sap.com/2017/05/21/step-2-with-sap-s4hana-cloud-sdk-helloworld-on-scp-classic/comment-page-1/#comment-454564.
Greetings
Chris
Thank you Chris. This problem was resolved, have moved past steps 2 and 3 and was able to run the app locally and on NEO and CF Accounts.
However now am getting an issue with this step 4, despite adding the TRUSTALL = TRUE in the destinations file, am getting the error: “Failed to execute Odata MetaData request”.
Below is the content of the destinatino file:
Relative path: application\localServerContent\config_master\service.destinations\destinations\ErpQueryEndpoint
Here is the odata while accessed direclty via the browser:
Thanks
Sudarshan
Hi Sudarshan,
can you give us a bit more details on your setup, e.g. where do you deploy the application? (Neo or CF, Local or Remote?)
The file you mentioned is only relevant if you want to deploy the application on a local Neo server. For the remote variants you need to set up the destination in the respective Cockpit and for Local Cloud Foundry deployment you need to adjust your environment variables, all as described in the blog post.
Greetings
Chris
Hi Alexander,
I am using vdm to call some backend OData service through an app deployed on SCP-CF. I am getting this error.
{"error":{"code":null,"message":{"lang":"en","value":"Failed to get current tenant: no RequestContext available. Have you correctly configured a RequestContextServletFilter or have you wrapped your logic in a RequestContextExecutor when executing background tasks that are not triggered by a request?"}}}
I have been able to make it work previously in a different app. The current app is a spring boot app. Could that be the cause of the issue? If so can you suggest a solution?
Thanks,
Sachin
Hello Sachin,
please make sure you have your Spring Boot Application class sufficiently annotated:
If the classes from com.sap.cloud.sdk still couldn't be loaded, take a look into the start up log. Maybe a (dependency) version conflict caused duplicate classes, leading to an invalid application state.
Best regards
Alexander
Hi Alexander,
I have succesfully created the initial stub using CF archtype and while using vdm i am getting this error.
no suitable method found for execute(no arguments)
[ERROR] method com.sap.cloud.sdk.s4hana.datamodel.odata.helper.FluentHelperBasic.execute(com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestinationProperties) is not applicable
[ERROR] (actual and formal argument lists differ in length)
[ERROR] method com.sap.cloud.sdk.s4hana.datamodel.odata.helper.FluentHelperRead.execute(com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestinationProperties) is not applicable
[ERROR] (actual and formal argument lists differ in length)
Thanks,
Aditya
Hi Aditya,
would be helpful to see your code.
Marco
Hi Aditya,
it seems like your archetype has loaded a “wrong”, not yet stable version of the SDK.
Please run the mvn generate code again with the version “RELEASE” instead of “LATEST”.
Greetings
Chris
Hi Chris,
with RELEASE its giving this error
Execution default of goal com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:2.19.1:usage-analytics failed: Plugin com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:2.19.1 or one of its dependencies could not be resolved: Failed to collect dependencies at com.sap.cloud.s4hana.plugins:s4sdk-maven-plugin:jar:2.19.1 -> com.sap.cloud.s4hana.plugins:usage-analytics:jar:2.19.2-SNAPSHOT
at the time of mvn clean install
Thanks
Aditya
Hi Aditya,
for this error please delete everything under the .m2/com/sap/cloud/... directory in your home directory.
This is due to some versioning issues in maven.
Greetings
Chris
Hi Alexander,
I've finished successfully doing the tutorial. Thank you a lot for this helpful article.
May I know how to add a Fiori UI on top of this service (OData endpoint)?
P.S.: If there is any blog teaching it, I would love to have it.
BR,
Pietro
Hi Pietro,
great to here!
For links on how to use SAPUI5/Fiori Elements I would forward you to your question on answers.sap.com: https://answers.sap.com/questions/12940024/how-to-consume-sap-cloud-sdk-via-fiori.html
Greetings
Chris
Hi Chris,
Thanks a lot. Actually, I posted the question here before learn about the SAP specialist community.
They´ve answered me, and I am going through the tutorial already.
Pietro
Hi Alexander,
we have the following scenario. Please let me know if this can be achieved by using the SAP Cloud SDK.
We want to develop a UI5 app on SCP Neo. The app should consume data from:
For this, the goal was to develop our own OData services that retrieve (and adapt) data from AIN, and mashes it up with the data from other sources.
The service then should be deployed on SCP Neo and consumed by the app.
Our first approach was to use the SDK for service development (https://blogs.sap.com/2017/10/17/introducing-the-sap-cloud-platform-sdk-for-service-development/). But here we got the information that this SDK is not really meant to be used for SCP Neo, and was replaced by the Application Programming Model.
Now I wanted to check the SAP Cloud SDK. But I am not sure if this can even work.
I was able to create and deploy to Neo the HelloWorld example successfully. But when I wanted to test the OData example, I got stuck with the following error:
I used the following command for the project creation:
mvn archetype:generate -DarchetypeGroupId=com.sap.cloud.sdk.archetypes -DarchetypeArtifactId=scp-neo-javaee7 -DarchetypeVersion=RELEASE
To make sure that it is not due to my previous tests, I also deleted the .m2\repository\com\sap\cloud folder.
Thanks and best regards,
Tobias
Hi Tobias,
would be good so see your servlet code as well as having your dependency tree. Pls provide the two.
Thanks
Marco
Hi Marco,
thanks so much for your answer.
Here is the code:
Error:
Dependencies:
Best regards,
Tobias
Hello Tobias,
looking at your code and at the error message I can fully understand that the compiler complains.
The misunderstanding is that you’re using code that used to work when using the SAP Cloud SDK in version 2, while you actually use SAP Cloud SDK in version 3 (see your dependency tree).
Please note that disclaimer at the top of this blog post that points this out.
In order to fix this particular compilation problem, you would need to supply the Destination instance as argument to the “execute” method. You can use the DestinationAccessor class to retrieve the Destination instance.
Best regards
Marco
Hello Marco,
thanks again!
Now I was able to retrieve my destination in the SCP by using the DestinationAccessor.
Taking into consideration that my source is not S4HANA, am I correct that I can use the
ODataQueryBuilder
to access the data that is delivered, e.g. select only specific columns, and make this available again as an Odata service?And would you mind to again give me some hints or even a little code snippet how to do this?
Thanks and best regards,
Tobias
Hi Tobias,
I understand that your source system provides an OData API, you want to consume this in your application and expose a sub set and/or a projection of this data in an OData service from your app?
If my understand is correct, I propose you go ahead to generate your own Virtual Data Model representing the source OData API. This allows type-safe consumption of your source OData API. Check out the respective blog post here: https://blogs.sap.com/2018/04/30/deep-dive-10-with-sap-s4hana-cloud-sdk-generating-java-vdm-for-s4hana-custom-odata-service/
Note that this blog post then touches upon Cloud SDK version 2 too, you might check out the updated tutorials that are linked from the disclaimer at the top.
Once you are able to consume your OData API with the VDM, you can expose that again in your own OData API. For this purpose, we recommend to leverage the SAP Cloud Platform SDK for service development, pls refer to this blog series: https://blogs.sap.com/2018/03/01/sap-cloud-platform-sdk-for-service-development-overview-of-blogs/
Thanks
Marco
Hi Alexander,
I am trying to setup ES5 demo system destination in https://account.hanatrial.ondemand.com/ and a java application to access the odata service (/sap/opu/odata/sap/SEPMRA_PO_APV).
Below is the code.
ODataQueryResult result = ODataQueryBuilder.withEntity("/sap/opu/odata/sap/SEPMRA_PO_APV", "PurchaseOrders").select("CurrencyCode", "DeliveryAddress", "DeliveryDateEarliest", "GrossAmount", "OrderedByName").build().execute("ES5_Demo");
When I deploy and run the code, I get
Unable to execute the OData operation : Failed to execute OData request.
In the log file
2020 03 01 11:40:09#+00#ERROR#com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache##P066870#https-jsse-nio-8041-exec-8#na#p066870trial#firstappapplication#web#p066870trial#na#na#na#na#Error occurred while populating metadata : java.net.NoRouteToHostException: No route to host (Host unreachable) (local port 52040 to address 10.117.33.60 (vsa7340647.nwtrial.od.sap.biz), remote port 443 to address 155.56.38.41) at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:874) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:368) at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:374) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) at com.sap.cloud.sdk.cloudplatform.connectivity.HttpClientWrapper.execute(HttpClientWrapper.java:101) at com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache.getEdm(GuavaMetadataCache.java:235) at com.sap.cloud.sdk.odatav2.connectivity.cache.metadata.GuavaMetadataCache.getEdm(GuavaMetadataCache.java:154) at com.sap.cloud.sdk.odatav2.connectivity.ODataQuery.loadMetadata(ODataQuery.java:372) at com.sap.cloud.sdk.odatav2.connectivity.ODataQuery.loadEntriesFromDestination(ODataQuery.java:303) at com.sap.cloud.sdk.odatav2.connectivity.ODataQuery.internalExecute(ODataQuery.java:246) at com.sap.cloud.sdk.odatav2.connectivity.ODataQuery.execute(ODataQuery.java:178) at com.sap.cloud.sdk.odatav2.connectivity.ODataQuery.execute(ODataQuery.java:227) at com.srini.cloud.sdk.tutorial.FlightServlet.doGet(FlightServlet.java:52) at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.sap.core.communication.server.CertValidatorFilter.doFilter(CertValidatorFilter.java:155) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.sap.cloud.sdk.cloudplatform.servlet.RequestContextServletFilter.lambda$doFilter$0(RequestContextServletFilter.java:197) at com.sap.cloud.sdk.cloudplatform.servlet.RequestContextCallable.call(RequestContextCallable.java:131) at com.sap.cloud.sdk.cloudplatform.servlet.RequestContextServletFilter.doFilter(RequestContextServletFilter.java:209) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.sap.cloud.sdk.cloudplatform.security.servlet.HttpCachingHeaderFilter.doFilter(HttpCachingHeaderFilter.java:82) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at com.sap.cloud.sdk.cloudplatform.security.servlet.HttpSecurityHeadersFilter.doFilter(HttpSecurityHeadersFilter.java:42) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.filters.RestCsrfPreventionFilter.doFilter(RestCsrfPreventionFilter.java:125) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44) at com.sap.core.connectivity.jco.session.ext.RequestTracker.invoke(RequestTracker.java:55) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:668) at com.sap.cloud.runtime.impl.bridge.security.AbstractAuthenticator.invoke(AbstractAuthenticator.java:206) at com.sap.cloud.runtime.kotyo.tomcat.support.CookieValve.invoke(CookieValve.java:38) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) at com.sap.core.tenant.valve.TenantValidationValve.invokeNextValve(TenantValidationValve.java:182) at com.sap.core.tenant.valve.TenantValidationValve.invoke(TenantValidationValve.java:97) at com.sap.js.statistics.tomcat.valve.RequestTracingValve.callNextValve(RequestTracingValve.java:113) at com.sap.js.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:59) at com.sap.core.js.monitoring.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:27) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:609) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:810) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1623) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:836)
Could you please assist?
Best Regards
Srini
Hi Srinivasan,
Regards,
Kavitha
Hi there, is there a blog or resource that shows how a post would be performed? receiving an incoming json payload and the posting to a target sap on-premise Odata service?
Hi Alexander Duemont is there a blog or resource that shows how a post would be performed? receiving an incoming json payload and the posting to a target sap on-premise Odata service?
Hi Alexander Duemont do you perhaps have any blogs or resources that can assist with performing a post to an on-premise odata service, in other words the servlet would receive a json payload in the incoming request, and then lookup the address from the destination and perform a post to an on premise SAP system?