Use FluentAPI's to execute against a HTTPClient instead of a destination name - sap-cloud-sdk

We want to use the VDM generated API's to execute against a Http client instead of a destination.
Currently the fluent api's work along the lines ::
service......execute(new ErpConfigContext(destinationName));
Is it Possible to have it work against a HTTP client.
Use Case :: We are trying to consume Odata Services in non CF environments.. where Destinations are not available.

Update: Starting with version 3.0.0 of the SAP Cloud SDK you are now able to create your own Destinations, so you are no longer reliant on Destinations provided by the SDK.
This might then look something like this:
HttpDestination httpDest = DefaultHttpDestination.builder("https://sap.com").build();
service.getAllEntities().execute(httpDest);
There is no direct possibility to do this via the VDM API as of version 2.19.1.
To circumvent this, however, you could override the DestinationFacade (cf. AbstractDestinationFacade) in the DestinationAccessor.
This would allow you to plug your "non-destination" concept into the VDM.

Related

When to use (decorate with) what and why - DefaultErpHttpDestination, DefaultHttpDestination?

Using java SAP Cloud SDK
I have to use com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.outbounddeliveryv2.batch.OutboundDeliveryV2ServiceBatch.execute(HttpDestinationProperties destination) to perform some updates on S/4 system. This method, execute takes an argument of type HttpDestinationProperties.
Since I need a destination, I am using below code to get destination:
HttpDestination destination = DestinationAccessor.getDestination("MyErpSystem").asHttp();
Since HttpDestination extends HttpDestinationProperties, we can safely pass it to execute. But according to step 4 of 'Connect to OData Service on Cloud Foundry Using SAP Cloud SDK' tutorial, the code for accessing destination looks like this:
ErpHttpDestination destination = DestinationAccessor.getDestination("MyErpSystem").asHttp().decorate(DefaultErpHttpDestination::new);
and then they pass that destintion to the execute method of the service.
My question is that since execute methods takes an argument of type HttpDestinationProperties, How would I know that I have to use DefaultErpHttpDestination? Same thing goes for DefaultHttpDestination.
I have following questions -
When and why should I wrap the destination in DefaultErpHttpDestination?
When and why should I wrap the destination in DefaultHttpDestination?
Why should I wrap the destination in above two wrappers at all?
This is an excellent question!
The context:
Of course you can keep using your original approach:
HttpDestination destination =
DestinationAccessor.getDestination("MyErpSystem").asHttp();
This is the recommended way for destinations targeting a generic HTTP service endpoint.
It loads the required destination properties for HTTP connections, e.g. URL, Authentication, ...
In the tutorials we are describing the integration with S/4HANA OData services:
HttpDestination destination =
DestinationAccessor.getDestination("MyErpSystem").asHttp()
.decorate(DefaultErpHttpDestination::new);
By "decorating" the HttpDestination instance with ERP properties, we enable additional S/4 related HTTP request headers: sap-client and sap-locale. With the above configuration, those values are read automatically from the destination service - if they are set.
Your questions (changed order):
"When and why should I wrap the destination in DefaultHttpDestination?"
DestinationAccessor#getDestination returns a generic Destination. In order to make sure we are dealing with HTTP (and not RFC) connections, you need to run #asHttp - as you already do. With the resulting HttpDestination instance, you can run HTTP queries like OData and REST. Depending on your use case, no additional wrapping is required.
For example, if you were about to use BAPI endpoints, then you'd need to run #asRfc instead. This method will check for different destination properties to make sure all required values are set.
"When and why should I wrap the destination in DefaultErpHttpDestination?"
It is recommended to wrap the destination in DefaultErpHttpDestination only when you are dealing with S/4 service endpoints and you rely on custom values for sap-client and sap-locale. The wrapping can be done at any time of your application runtime, as long as it happens before #execute(HttpDestinationProperties) method.
If you do not want to wrap it a second time, then you'd need to manually manage the HTTP request headers for sap-client and sap-locale.
"Why should I wrap the destination in above two wrappers at all?"
This is the API contract. It makes sure all required destination properties are correctly set before even invoking the actual request. The (optional) ERP flavored wrapping of the destination instance was provided to make sure all S/4 properties are automatically considered as well.

Accessing Amazon MWS inBound shipments

I want to access MWS Inbound Shipments API form C# in a similar way I do with the Amazon Reports using MarketplaceWebService
But I don't know how to to it.
For example how can I do this call form c# : https://docs.developer.amazonservices.com/en_US/fba_inbound/FBAInbound_ListInboundShipmentItems.html?
The easiest and quickest approach is to download the C# SDK for MWS, where you can create a client and call the ListInboundShipmentItems method directly. For this particular operation, ShipmentId is required. All you need to do is add your AWS keys and token (if applicable) and make the call. I noticed that the SDK used to be publicly available, but I think now you are required to log in with a seller account.
If you are not using the SDK, your request should look like this:
http://mws.amazonaws.com/FulfillmentInboundShipment/2010-10-01/
?Action=ListInboundShipmentItems
&Version=2010-10-01
&AWSAccessKeyId=1QZHP81EXAMPLEN5R44N
&MWSAuthToken=amzn.mws.4ea38b7b-f563-7709-4bae-87aeaEXAMPLE
&SignatureVersion=2
&SignatureMethod=HmacSHA256
&Signature=VY6sqvdk01VeEXAMPLEG0Vh4oj3
&Timestamp=2015-12-01T02:40:36Z
&SellerId=1234567890
&ShipmentId=SSF85DGIZZ3OF1
Make sure you read the developer guide too.

Pass parameters from C# function app to another Javascript function app in Azure

I need to set up an application in Azure and make communicate 2 functions (one written in C# and one written in JavaScript).
The C# fragment consists in analyzing a XML feed, get the data and save in objects then finally send them to the other JavaScript function by parameter.
I did read that we could establish communication between both functions using HTTP calls but is it possible to do it with parameters ?
If not, would have any suggestions in order to achieve something like this properly? I'm getting started with Azure and i don't have enough visibility to know what is recommened in such a situation
Thank you for your advices
Yes, this is absolutely possible. How you do this is up to you. If you look at the default HTTP trigger templates, you can see that they take parameters (for example, as query string parameters). You can find more examples in the HTTP and webhook recipes documentation.
You can use other trigger types for cross-function communication as well. Take a look at this documentation for related best practices: https://learn.microsoft.com/en-us/azure/azure-functions/functions-best-practices#cross-function-communication

Can Azure Functions be used with URI path IDs?

I am wondering if it is possible to configure an Azure Function App to accept a URI-path ID as is typically used in RESTful services, e.g. /api/foo/1, where the function is foo. I haven't been able to find documentation on this and the binding information that I have found suggests that this isn't possible (I don't see a way to map it). It doesn't "just work" with the typical HTTP trigger (which supports /api/foo?id=1). In that configuration one receives a 404 response, I'm guessing because it doesn't know to call the foo function with the ID suffix in the URI.
In case it matters, I'm using C# to write my function.
You are correct that URI parameters are not supported at this time. If you'd like, you can create a feature suggestion for this here in our repo. Thanks :)

Using OData to execute a remote Domain Service method

As far as I got it so far, OData is more meant to consume data, i.e. in a read-only manner. I want to ask whether it's intended to use OData to invoke remote functions, for example a Domain Service's method.
When looking at the OData 4.0 spec, chapter 4.3 "Addressing Entities", there are indeed terminologies like actionCall, entityFunctionCall etc. But this so far is of course also only meant for "serving", I assume.
I'd like to do something like http://example.org/service/BankAccountDomainService/ApproveBankAccount(abcde-123456)... Does that make sense?
If I understand you correctlu, you want to invoke an unbound action, which is called "Action Import" since your action "ApproveBankAccount" does not bounded to any type....
According to the Odata Protocol, the folloding URL should be "POST": the "Account" should be included in Payload.
URL: http://example.org/service/BankAccountDomainService/ApproveBankAccount()
Payload: { abcde-123456 }
Aternatively, you can also design bounded action "Approve" on entity type "BankAccount", the posted URL should be:
http://example.org/service/BankAccountDomainService/BankAccount(abcde-12345)/NameSpace.Approve()
OData is a standardized protocol for creating and consuming data APIs. OData builds on core protocols like HTTP and commonly accepted methodologies like REST. The result is a uniform way to expose full-featured data APIs.
Except providing functions and actions bound to entities, OData also provides service level functions and actions.
Please reference this URL for the sample:
https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/ODataActionsSample/
But it is based on OData v3, and there will soon be samples for OData v4.

Resources