Introduction
The SAP BTP Document Management Service(DMS) helps in managing business documents. It’s based on the OASIS (Organization for the Advancement of Structured Information Standards) industry standard CMIS (Content Management Interoperability Services) and includes features like versioning, hierarchies, access control, and document management.
In this blog, I am going to explain how to create a custom spring boot application in SAP BTP cloud foundry and integrate it with SAP BTP DMS.
Business Scenario
Let’s say we have a requirement where we need to replicate documents from different SAP SaaS applications(e.g. SAP SuccessFactors) to SAP BTP Document Management Service. In this case, we can create a custom Java Spring Boot application and deploy it to BTP Cloud Foundry as an MTA(multi-target application). Spring Boot application can have scheduled Cron Jobs(if there is any need for automation) or REST APIs(to be triggered from UI and any other application) to interact with DMS rest APIs and SuccessFactors.
Or if you have a custom application, and you want to use SAP BTP DMS for document management then this example will be helpful.
Technical Details
In this blog, I will create a maven-based spring boot application(MTA) and will expose a REST API that will upload a document in the DMS. Spring Boot application will interact with DMS REST API through BTP destinations. The main reason for using BTP destinations is the DMS authentication will be taken care of by BTP destinations. I will be using SAP Cloud SDK to interact with BTP Destinations from Spring Boot.
Architecture
Prerequisite
Access to SAP BTP Cloud Foundry, and org & space are created.Access to BTP destination.Access to SAP BTP DMS service and DMS repository is created.Eclipse(with Spring tool suite and Lombok plugin) and JDK(1.8) are installed in the development system.Cloud Foundry command line interface (CF CLI) is installed, and the path is set in the environment variable.Cloud MTA build tool (MBT) is installed, and the path is set in the environment variable.Make tool is installed, and the path is set in the environment variable.
Create a destination in SAP BTP for DMS service
Please make sure the URL contains the repository ID and folder name(if no folder is created in the repository, then use root)
Steps to create the Application
Create a maven based spring boot project in Eclipse.
Open the pom.xml file and replace it with the below code.
<?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!– lookup parent from repository –>
</parent>
<groupId>com.sl</groupId>
<artifactId>SampleSAPBTPApplication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SampleSAPBTPApplication</name>
<description>Sample SAP BTP App with Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>1.8</java.version>
<swagger.version>2.9.2</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-cf</artifactId>
<version>3.46.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.10</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
</project>
Create a Java class and replace the code with the below code (please check the package and class name).
package com.sl.demo.api;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpClientAccessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestination;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@RestController
public class BTPDMSService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* Attaches a generic file to an existing work.
*/
@RequestMapping(method = RequestMethod.POST, path = “/uploadFile”, produces = “application/json”, consumes = “multipart/form-data”)
@ApiOperation(value = “Attaches a generic file to an existing work.”)
@ApiResponses({ @ApiResponse(code = 200, message = “OK”, responseContainer = “Map”, response = Long.class),
@ApiResponse(code = 400, message = “Bad request”),
@ApiResponse(code = 401, message = “Unauthorized, basic auth required”),
@ApiResponse(code = 403, message = “Forbidden”) })
public String uploadFile(@RequestParam(“attachment”) MultipartFile file) throws IOException {
log.info(“Upload file started”);
String DESTINATION_NAME = “MyDestinationForDMS”;
byte[] content = file.getBytes();
String filename = file.getOriginalFilename();
String contentType = file.getContentType();
HttpDestination destination = DestinationAccessor.getDestination(DESTINATION_NAME).asHttp();
HttpClient httpclient = HttpClientAccessor.getHttpClient(destination);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
log.info(“Uploading file : {}”, filename);
builder.addTextBody(“cmisaction”, “createDocument”);
builder.addTextBody(“propertyId[0]”, “cmis:name”);
builder.addTextBody(“propertyValue[0]”, “testSudhir01.json”);
builder.addTextBody(“propertyId[1]”, “cmis:objectTypeId”);
builder.addTextBody(“propertyValue[1]”, “cmis:document”);
builder.addTextBody(“filename”, “testSudhir01”);
builder.addTextBody(“_charset_”, “UTF-8”);
builder.addTextBody(“includeAllowableAction”, “true”);
builder.addTextBody(“succinct”, “true”);
builder.addBinaryBody(“media”, content, ContentType.create(contentType), filename);
HttpEntity postData = builder.build();
HttpPost httpPost = new HttpPost();
httpPost.setEntity(postData);
HttpResponse response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
log.info(“Response from post File: {}”, response.getStatusLine().getStatusCode());
log.info(“******** Response Body **********: {}”, EntityUtils.toString(entity));
return “Executed with status Code:” + response.getStatusLine().getStatusCode();
}
}
Create a Java class for swagger config and replace the code with the below code.
package com.sl.demo.swagger;
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@Import(BeanValidatorPluginsConfiguration.class)
public class SpringFoxConfig {
String appTitle = “DMS Integration”;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage(parentPackageName())).paths(PathSelectors.ant(“/**”)).build();
}
private String parentPackageName() {
String thisPackageName = getClass().getPackage().getName();
int lastDotPos = thisPackageName.lastIndexOf(‘.’);
String parentPackageName = thisPackageName.substring(0, lastDotPos);
return parentPackageName;
}
private ApiInfo apiInfo() {
return new ApiInfo(appTitle + ” API”, “This is the API for the ” + appTitle + ” application.”, “v1”, null,
new Contact(“SL”, “”, “test@sl.com”) , null, null,
Collections.EMPTY_LIST);
}
}
Create a mta.yaml file in the workspace (where the project is created) and paste the below code into the mta.yaml file.
_schema-version: ‘3.0.0’
ID: com.sl.sampleApplication
description: Sample Application
version: 1.0.0
modules:
– name: SampleSAPBTPApplication
type: java
path: SampleSAPBTPApplication
parameters:
stack: cflinuxfs4
memory: 2048M
instances: 1
buildpacks:
– java_buildpack
build-parameters:
builder: custom
timeout: 10m
build-result: target/SampleSAPBTPApplication-*.jar
commands:
– mvn clean install -Dcheckstyle.skip -DskipTests=true -Pdev
requires:
– name: BTPDestinationResource
# Binding services
resources:
– name: BTPDestinationResource
type: org.cloudfoundry.managed-service
parameters:
service-name: MyDestinationInstance
service-plan: lite
service: destination
Select the project in Eclipse and update(Maven) the project, please make sure there is no compilation error.
Build and Deployment
Open the command prompt from the workspace(where the mta.yaml file is placed) folder.
Build the project to generate the “.tar” file by using the below command in the command prompt.
mbt build -t SampleSAPBTPApplication/generatedTAR –mtar SampleApplication.tar
If the build is successful, then SampleApplication.tat file will be created in the generatedTAR folder.
Use the below commands in the command prompt to log in to the BTP cloud foundry and deploy the project. (It will prompt you to enter the username and password for BTP. it will prompt you to select org and space if there is more than one)
cf login -a https://api.<CF API host>.hana.ondemand.comcf deploy SampleSAPBTPApplication/generatedTAR/SampleApplication.tar
Once the deployment is successful, it will be shown in the applications under the space.
If everything is fine, then the status will be showing as started and the application can be accessed by using the URL shown under application routes.
Testing
The application can be tested by using the swagger URL from the application as mentioned below.
https://<app URL-dev-samplesapbtpapplication.hana.ondemand.com>/swagger-ui.html
Click on “/uploadFile” API to test the file upload functionality.
Choose any file and click on “Execute”.If everything is fine, then the file will be uploaded to DMS and can be found in DMS.
Conclusion
This blog is written based on my learning and understnading, please feel free to comment for the improvement. Same thing can be achieved by creating a CAP appllication, in the next blog I will explain how to achieve the same requirement through a CAP (Java) application.
If anybody is interested for the code, please feel free to pull it from git.
https://github.com/sudhirlenkagit/MTASpringBootIntegratesDMS.git
Thanks,
Sudhir Lenka.
IntroductionThe SAP BTP Document Management Service(DMS) helps in managing business documents. It’s based on the OASIS (Organization for the Advancement of Structured Information Standards) industry standard CMIS (Content Management Interoperability Services) and includes features like versioning, hierarchies, access control, and document management.In this blog, I am going to explain how to create a custom spring boot application in SAP BTP cloud foundry and integrate it with SAP BTP DMS.Business ScenarioLet’s say we have a requirement where we need to replicate documents from different SAP SaaS applications(e.g. SAP SuccessFactors) to SAP BTP Document Management Service. In this case, we can create a custom Java Spring Boot application and deploy it to BTP Cloud Foundry as an MTA(multi-target application). Spring Boot application can have scheduled Cron Jobs(if there is any need for automation) or REST APIs(to be triggered from UI and any other application) to interact with DMS rest APIs and SuccessFactors.Or if you have a custom application, and you want to use SAP BTP DMS for document management then this example will be helpful.Technical Details In this blog, I will create a maven-based spring boot application(MTA) and will expose a REST API that will upload a document in the DMS. Spring Boot application will interact with DMS REST API through BTP destinations. The main reason for using BTP destinations is the DMS authentication will be taken care of by BTP destinations. I will be using SAP Cloud SDK to interact with BTP Destinations from Spring Boot.ArchitecturePrerequisite Access to SAP BTP Cloud Foundry, and org & space are created.Access to BTP destination.Access to SAP BTP DMS service and DMS repository is created.Eclipse(with Spring tool suite and Lombok plugin) and JDK(1.8) are installed in the development system.Cloud Foundry command line interface (CF CLI) is installed, and the path is set in the environment variable.Cloud MTA build tool (MBT) is installed, and the path is set in the environment variable.Make tool is installed, and the path is set in the environment variable.Create a destination in SAP BTP for DMS service Please make sure the URL contains the repository ID and folder name(if no folder is created in the repository, then use root)Steps to create the ApplicationCreate a maven based spring boot project in Eclipse.Open the pom.xml file and replace it with the below code. <?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!– lookup parent from repository –>
</parent>
<groupId>com.sl</groupId>
<artifactId>SampleSAPBTPApplication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SampleSAPBTPApplication</name>
<description>Sample SAP BTP App with Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>1.8</java.version>
<swagger.version>2.9.2</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
<artifactId>scp-cf</artifactId>
<version>3.46.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.10</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${swagger.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<packaging>war</packaging>
</project> Create a Java class and replace the code with the below code (please check the package and class name). package com.sl.demo.api;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpClientAccessor;
import com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestination;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@RestController
public class BTPDMSService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* Attaches a generic file to an existing work.
*/
@RequestMapping(method = RequestMethod.POST, path = “/uploadFile”, produces = “application/json”, consumes = “multipart/form-data”)
@ApiOperation(value = “Attaches a generic file to an existing work.”)
@ApiResponses({ @ApiResponse(code = 200, message = “OK”, responseContainer = “Map”, response = Long.class),
@ApiResponse(code = 400, message = “Bad request”),
@ApiResponse(code = 401, message = “Unauthorized, basic auth required”),
@ApiResponse(code = 403, message = “Forbidden”) })
public String uploadFile(@RequestParam(“attachment”) MultipartFile file) throws IOException {
log.info(“Upload file started”);
String DESTINATION_NAME = “MyDestinationForDMS”;
byte[] content = file.getBytes();
String filename = file.getOriginalFilename();
String contentType = file.getContentType();
HttpDestination destination = DestinationAccessor.getDestination(DESTINATION_NAME).asHttp();
HttpClient httpclient = HttpClientAccessor.getHttpClient(destination);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
log.info(“Uploading file : {}”, filename);
builder.addTextBody(“cmisaction”, “createDocument”);
builder.addTextBody(“propertyId[0]”, “cmis:name”);
builder.addTextBody(“propertyValue[0]”, “testSudhir01.json”);
builder.addTextBody(“propertyId[1]”, “cmis:objectTypeId”);
builder.addTextBody(“propertyValue[1]”, “cmis:document”);
builder.addTextBody(“filename”, “testSudhir01”);
builder.addTextBody(“_charset_”, “UTF-8”);
builder.addTextBody(“includeAllowableAction”, “true”);
builder.addTextBody(“succinct”, “true”);
builder.addBinaryBody(“media”, content, ContentType.create(contentType), filename);
HttpEntity postData = builder.build();
HttpPost httpPost = new HttpPost();
httpPost.setEntity(postData);
HttpResponse response = httpclient.execute(httpPost);
HttpEntity entity = response.getEntity();
log.info(“Response from post File: {}”, response.getStatusLine().getStatusCode());
log.info(“******** Response Body **********: {}”, EntityUtils.toString(entity));
return “Executed with status Code:” + response.getStatusLine().getStatusCode();
}
} Create a Java class for swagger config and replace the code with the below code. package com.sl.demo.swagger;
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@Import(BeanValidatorPluginsConfiguration.class)
public class SpringFoxConfig {
String appTitle = “DMS Integration”;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage(parentPackageName())).paths(PathSelectors.ant(“/**”)).build();
}
private String parentPackageName() {
String thisPackageName = getClass().getPackage().getName();
int lastDotPos = thisPackageName.lastIndexOf(‘.’);
String parentPackageName = thisPackageName.substring(0, lastDotPos);
return parentPackageName;
}
private ApiInfo apiInfo() {
return new ApiInfo(appTitle + ” API”, “This is the API for the ” + appTitle + ” application.”, “v1”, null,
new Contact(“SL”, “”, “test@sl.com”) , null, null,
Collections.EMPTY_LIST);
}
} Create a mta.yaml file in the workspace (where the project is created) and paste the below code into the mta.yaml file. _schema-version: ‘3.0.0’
ID: com.sl.sampleApplication
description: Sample Application
version: 1.0.0
modules:
– name: SampleSAPBTPApplication
type: java
path: SampleSAPBTPApplication
parameters:
stack: cflinuxfs4
memory: 2048M
instances: 1
buildpacks:
– java_buildpack
build-parameters:
builder: custom
timeout: 10m
build-result: target/SampleSAPBTPApplication-*.jar
commands:
– mvn clean install -Dcheckstyle.skip -DskipTests=true -Pdev
requires:
– name: BTPDestinationResource
# Binding services
resources:
– name: BTPDestinationResource
type: org.cloudfoundry.managed-service
parameters:
service-name: MyDestinationInstance
service-plan: lite
service: destination Select the project in Eclipse and update(Maven) the project, please make sure there is no compilation error.Build and DeploymentOpen the command prompt from the workspace(where the mta.yaml file is placed) folder.Build the project to generate the “.tar” file by using the below command in the command prompt. mbt build -t SampleSAPBTPApplication/generatedTAR –mtar SampleApplication.tar If the build is successful, then SampleApplication.tat file will be created in the generatedTAR folder. Use the below commands in the command prompt to log in to the BTP cloud foundry and deploy the project. (It will prompt you to enter the username and password for BTP. it will prompt you to select org and space if there is more than one) cf login -a https://api.<CF API host>.hana.ondemand.comcf deploy SampleSAPBTPApplication/generatedTAR/SampleApplication.tar Once the deployment is successful, it will be shown in the applications under the space.If everything is fine, then the status will be showing as started and the application can be accessed by using the URL shown under application routes.TestingThe application can be tested by using the swagger URL from the application as mentioned below.https://<app URL-dev-samplesapbtpapplication.hana.ondemand.com>/swagger-ui.html Click on “/uploadFile” API to test the file upload functionality.Choose any file and click on “Execute”.If everything is fine, then the file will be uploaded to DMS and can be found in DMS.ConclusionThis blog is written based on my learning and understnading, please feel free to comment for the improvement. Same thing can be achieved by creating a CAP appllication, in the next blog I will explain how to achieve the same requirement through a CAP (Java) application.If anybody is interested for the code, please feel free to pull it from git.https://github.com/sudhirlenkagit/MTASpringBootIntegratesDMS.git Thanks,Sudhir Lenka. Read More Technology Blogs by Members articles
#SAP
#SAPTechnologyblog
+ There are no comments
Add yours