Skip to Content
Technical Articles

Dynamic Destination Creation in a Subscriber’s Account for a SaaS Application

Pre Read

This blog focuses on one of the implementation concepts as per my understanding related to the SaaS model. If you are not aware of what is SaaS model or how its implemented in SAP Business Technology platform then you can refer to the following Blogs:

<Blog>

Now let’s talk about the goal of this blog.

In the blog, we will see how to dynamically create a destination in subscriber’s subaccount and access it from the subscriber’s account.

The assumed use case:

A SaaS provider is building a multitenant SaaS extension application which will be connected to Subscriber’s SAP S/4 HANA and SAP SuccessFactors account. There’s one issue with this flow. How to ask the subscriber to provide the correct configuration like name, authentication properties? what if the user enters some wrong value?

The multitenant application will not be able to access the destination and application will not function properly.

The Solution:

Our multitenant application will be having destination service bound to it. When the subscriber tries to access the application, the destination token is generated from subscriber’s tenant and this gives the multitenant application access to the destinations in subscriber’s account. Now, all we have to do is to check if the subscriber’s account is having the required destination, if not then Create one with the required configuration and dummy value. The value can be later changed by the subscriber and hence they won’t need to share any credentials with the provider.

 

Code: 

I’m assuming you have created destination re-use service, subscription and routes already, if not please follow this blog:SAAS Generator and Concepts

In this code snippet, I have tried to check for a destination when the user is querying the destination service, In the first attempt, it will give 404, internally it will be creating the destination. when a user tries to access the destination for the second time, it will return the destination.

//dest: destination service credentials
//subdomain: Subscriber's subdomain to get the authentication token
//Destination: Name of the destination to be searched or created
async function getDestination(dest, subdomain, destination) {
    try {
        // use subscriber's subdomain to authenticate
        let url = dest.url.split('://')[0] + '://' + subdomain + dest.url.slice(dest.url.indexOf('.'));
        try {
            let options1 = {
                method: 'POST',
                url: url + '/oauth/token?grant_type=client_credentials',
                headers: {
                    Authorization: 'Basic ' + Buffer.from(dest.clientid + ':' + dest.clientsecret).toString('base64')
                }
            };
            let res1 = await axios(options1);
//options1 is the bearer token for destination generated from subscriber's tenant, this will be used to //access destination
            try {
                options2 = {
                    method: 'GET',
                    url: dest.uri + '/destination-configuration/v1/destinations/' + destination,
                    headers: {
                        Authorization: 'Bearer ' + res1.data.access_token
                    }
                };
                let res2 = await axios(options2);
    
                return res2.data.destinationConfiguration;
            } catch (err) {
             //there's no destination in subscriber's account and now we create a template  
                try {
                    var data = {
                        "Name": "mydest",
                        "Type": "HTTP",
                        "URL": "https://www.sap.com",
                        "Authentication": "NoAuthentication",
                        "ProxyType": "Internet"
                    };
                    options2 = {
                        method: 'POST',
                        url: dest.uri + '/destination-configuration/v1/subaccountDestinations',
                        data : data,
                        headers: {
                            Authorization: 'Bearer ' + res1.data.access_token
                        }
                    }
                    let res3 = await axios(options2);
                } catch (err) {
                    console.log(err);
                }
                    console.log(err.stack);
                return err.message;
            }
        } catch (err) {
            console.log(err.stack);
            return err.message;
        }
    } catch (err) {
        console.log(err.stack);
        return err.message;
    }
};

 

Output:

Attempt 1:

"Request failed with status code 404"

Destination%20configuration

 

Attempt 2:

{
"Name": "mydest",
"Type": "HTTP",
"URL": "https://www.sap.com",
"Authentication": "NoAuthentication",
"ProxyType": "Internet"
}

 

 

Bingo!!.

We got the destination created and our subscriber can now replace the template with right credentials.

 

Post Read:

Now that you know how to create destinations dynamically from a multitenant application, you can see API hub for further details and follow the following blogs and links to know more.

https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/7e306250e08340f89d6c103e28840f30.html

https://blogs.sap.com/2019/07/28/how-to-create-destination-in-sap-cloud-platform-cockpit-and-types-we-support-in-sap-leonardo-iot-action

https://blogs.sap.com/2020/08/03/multi-tenancy-of-destination-service-with-cloud-foundry-applications/

Happy Coding 💻 </Blog>

Be the first to leave a comment
You must be Logged on to comment or reply to a post.