I'm developing a Java App on SAP SCP Neo which is using the S/4 SDK for platform abstraction. I'm struggling to create a background task that is tenant aware. That means, when using the S/4SDK platform abstraction methods like com.sap.cloud.sdk.cloudplatform.tenant.TenantAccessor or DestinationAccessor to access the tenant information or to retrieve a destination, these methods shall return the tenant specific information, as if one would call them from a typical tenant specific web request.
When calling the S/4SDK accessor methods I wrapped them with a callable and execute it with the RequestContextExecutor. This works fine but as I do not see any way to provide a tenant, it is unclear to me how to solve my problem. I saw that a default listener is used inside the S/4 SDK, so I assume its running in the context of the provider account. Please find below a sample to retrieve a destination.
Destination getDestination(String destinationName) {
// Request Context is present when action is triggered by a web request
if (RequestContextAccessor.getCurrentRequest().isPresent()){
return DestinationAccessor.getDestination(destinatioName);
}
// Use RequestContextExecutor if we are called from a background task
Callable<Destination> callable = new Callable<Destination>() {
@Override
public Destination call() {
return DestinationAccessor.getDestination(destinatioName);
}
};
// TODO this defaults the contexts to the provider account.
return new RequestContextExecutor().execute(callable);
}
Motivation:
When using the RequestContextExecutor on SAP CP Neo, this will return rely on the provider tenant as you correctly noticed.
Currently, the S/4 SDK does not offer a generic way to execute code on behalf of another tenant. This is mainly due to the fact that tenant information is represented differently across SAP CP environments. For example, on Cloud Foundry, a tenant is encoded as part of a "zid" field within a JSON Web Token. Therefore, it is tricky to run code on behalf of different tenants. So on SAP CP Cloud Foundry, you would actually not have this fallback to the provider tenant.
Still, for SAP CP Neo, I would expect that you should be able to use the following approach in order to run a Callable
based on the context of another tenant. This should then allow you to retrieve the current tenant as intended within the context of the respective Callable
.
ScpNeoTenant currentTenant = (ScpNeoTenant)TenantAccessor.getCurrentTenant();
TenantContext currentTenantContext = currentTenant.getTenantContext();
currentTenantContext.execute("anotherTenantId", new Callable<MyResult>() {
@Override
public MyResult call() {
return new RequestContextExecutor().execute(new Callable<MyResult>() {
@Override
public MyResult call() {
Tenant tenant = TenantAccessor.getCurrentTenant();
// ...
return myResult;
}
});
}
});
I have not tested this yet, so please let me know if this works!