Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Muniyappan
Active Contributor
Please use this approach for taking backup of your trial or personal CPI packages. Not recommended for projects. 

Part 2:

https://blogs.sap.com/2023/09/06/part-2-upload-integration-packages-to-cpi-tenant-from-google-drive/

Overview


SAP BTP trial account can be used only for 90 days and beyond that period, account will get deleted. Let us say if you are using trial account for exploring cpi scenarios, then you can use it for 90 days. So whenever your trial period ends, you will lose all your flows. It is quite difficult to handle when you need to take backup as you need to download the packages one by one manually.

There are many ways to download the packages. Here I present how to download integration packages from your trial tenant and store it in google drive. You can schedule your iflow so that backup is taken periodically.

Prerequisites


Google Drive Instance In Open Connector


I have used Cloud integration along with open connector to achieve this. First create your google drive instance in open Open connector as explained in the below blog.

https://blogs.sap.com/2019/01/01/openconnectors-googledrive-integration-made-simple-with-sap-cpi-sap...

Once you are done with it, you can test the api and check if you are able to reach google drive. I have checked mine and I am able to retrieve the file and upload.

 

This is the API method used for uploading the files into google drive folder.



CPI ODATA


To download integration packages we can make use of  Odata APIs available for CPI. Here I am using this method.


 

 

ODATA API OAuth Credentials


You can set up your OAuth credentials for calling ODATA API.

https://engswee.github.io/flashpipe/oauth_client.html

Once credential is generated, we can add it to CPI security materials as Oauth 2 client credentials type.

 


 

 

Before you proceed, make sure

  1. All artifacts are not in draft mode.

  2. Make list of configure only type packages as we can not download these packages. I had around 18 packages in my tenant and one package is configure only. And this can not be downloaded.





Download Single Package


Here we try to download single integration package by providing the package id in the end url.


 

  1. Request reply : This step will make a Rest API call to download the integration package.

  2. Script : will convert the incoming zip payload into binary data and finally create a multi form payload.I have referred  this blog to write this groovy script. SAP Cloud Platform Open Connectors – Post payload to GoogleDrive from Integration Service .Basically we are reading the zip file as input stream and creating output as output stream.
    package com.formdata

    import com.sap.gateway.ip.core.customdev.util.Message;
    import java.util.HashMap;
    import java.text.SimpleDateFormat


    def ByteArrayOutputStream getMultiPartBody(payload, filename, id) {
    String charset = "US-ASCII";
    def LINEFEED = "\r\n";

    def output = new ByteArrayOutputStream();
    output.write(("--"+ id).getBytes(charset));
    output.write(LINEFEED.getBytes(charset));
    output.write(("Content-Disposition: form-data; name=\"file\"; filename=\""+filename+"\"").getBytes(charset));
    output.write(LINEFEED.getBytes(charset));

    output.write("Content-Type: application/zip".getBytes(charset));
    output.write(LINEFEED.getBytes(charset));
    output.write(LINEFEED.getBytes(charset));

    int nextByte
    while ((nextByte = payload.read()) != -1) {
    output.write(nextByte)
    }


    output.write(LINEFEED.getBytes(charset));


    output.write(("--"+ id + "--").getBytes(charset));

    return output;
    }

    def Message processData(Message message) {
    String charset = "US-ASCII";
    def id = "cpi";
    def filename = "P04RoutingPackage.zip"
    def ByteArrayOutputStream output = getMultiPartBody(message.getBody(java.io.InputStream),filename,id);

    message.setBody(output)
    return message;
    }


  3. Content Modifier : This step will add auth headers which are used to call open connector URL.Content-Type : multipart/form-data; boundary=cpiAccept: application/jsonAuthorization : Authcode(taken from open connector)

  4. Finally we will call Open connector API to upload the zip file into google drive.


 

Once we run the iflow, we can see that the integration package is downloaded and uploaded into google drive  folder successfully.



Download Multiple Packages


So now let us try to download all the integration packages available in the tenant and upload all into google drive folder. As mentioned before make sure artifacts are not in draft status and package type should be editable.

 

We are going to get all package details and split into multiple xmls and each xml file will contain one package details. We will make use of Package Id to download and Package name for naming zip file when storing it in drive.

 

We are using value mapping to skip downloading packages. This is explained in step 6.

 


 

 

  1.  Request reply: This will call ODATA api to read all package details and this will return output in xml format.

  2. In order to get package details, we will use filter step. Please note that you have to add the namespace Mapping for few namespace prefixes.Namespace mapping:

  3. We will add root node to make the xml well formatted,  so that it can be split in the next step

  4. Split step will split the input and produced multiple xml where each xml will represnt separate package.

  5. We will read the package information such as package id and package name and add it in the property.These two properties will be used in the up coming steps.

  6. Groovy script will check if the value mapping table has the incoming package Id, if it presents, then we will not consider for downloading. Again value mapping table is not used for conversion purpose. Just for filtering purpose. Let us say you have 10 packages are there and you dont want to download 2 packages, then You can add these 2 in the value mapping table, so that those 2 packages will not be downloaded. This is the reason value mapping table is used along with routing step.As explained above, here I am keeping one entry in the value mapping which is MicrosoftSharePointAdapterforSAPIntegrationSuite. This can not be downloaded as it is type of configure only.
    package com.valueMapping
    /* Refer the link below to learn more about the use cases of script.
    https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/148851bf8192412cba1f9d2c17f...

    If you want to know more about the SCRIPT APIs, refer the link below
    https://help.sap.com/doc/a56f52e1a58e4e2bac7f7adbf45b2e26/Cloud/en-US/index.html */
    import com.sap.gateway.ip.core.customdev.util.Message;
    import java.util.HashMap;
    import com.sap.it.api.mapping.*;
    import com.sap.it.api.ITApiFactory;
    import com.sap.it.api.ITApi;
    import com.sap.it.api.mapping.ValueMappingApi;
    def Message processData(Message message) {

    def isFilter = true
    def packageId = message.getProperties().get("packageID")
    def valueMapApi = ITApiFactory.getApi(ValueMappingApi.class, null);
    def value = valueMapApi.getMappedValue('Source', 'S_pckg', packageId, 'Target', 'T_pckg')
    if(value==null)
    {
    isFilter = false
    }

    message.setProperty("isFilter",isFilter );

    return message;
    }​

     

  7. Routing condition

  8. Request reply step: configure the url
    https://url/api/v1/IntegrationPackages('${property.packageID}')/$value

  9. Here same script used which is explained in the single package download . Here file name is read from property instead of hardcoded one.
    package com.formdata

    import com.sap.gateway.ip.core.customdev.util.Message;
    import java.util.HashMap;
    import java.text.SimpleDateFormat


    def ByteArrayOutputStream getMultiPartBody(payload, filename, id) {
    String charset = "US-ASCII";
    def LINEFEED = "\r\n";

    def output = new ByteArrayOutputStream();
    output.write(("--"+ id).getBytes(charset));
    output.write(LINEFEED.getBytes(charset));
    output.write(("Content-Disposition: form-data; name=\"file\"; filename=\""+filename+"\"").getBytes(charset));
    output.write(LINEFEED.getBytes(charset));

    output.write("Content-Type: application/zip".getBytes(charset));
    output.write(LINEFEED.getBytes(charset));
    output.write(LINEFEED.getBytes(charset));

    int nextByte
    while ((nextByte = payload.read()) != -1) {
    output.write(nextByte)
    }

    output.write(LINEFEED.getBytes(charset));


    output.write(("--"+ id + "--").getBytes(charset));

    return output;
    }

    def Message processData(Message message) {
    String charset = "US-ASCII";
    def id = "cpi";
    // def filename = "PI_test.zip"

    def filename = message.getProperties().get("packageName");
    def ByteArrayOutputStream output = getMultiPartBody(message.getBody(java.io.InputStream),filename,id);

    message.setBody(output)
    return message;
    }

     

  10. Content modifier will add the necessary headers like Auth and content type etc

  11. Here we are making use of package name which is in property to construct the URL query parameter


Once you are done with it, you can run the flow to check if all packages are downloaded and saved into google drive folder.

 


 


 

You might see errors if any package is having artifacts in draft mode or package is not available for downloading( ie configure only).

You can also use this approach to save the packages in SFTP folder, One drive, dropbox, Sharepoint. etc. by adjusting the flow based on the requirement.
6 Comments
Labels in this area