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: 
Sharadha1
Active Contributor
I am back with yet another blog about one of the services in SAP Cloud Platform - 'SAP Cloud Platform Document Service'. The document service offers persistent storage for content and provides additional functionality. It also provides a standardized interface for content using the OASIS CMIS standard.

As always, SAP has provided good amount of documentation to start exploring the service - link. The documentation covers the following two scenarios in detail. (Possible deployment scenarios are discussed here - Deployment Options)

1. Consuming the Document service from a Java application - Java application
2. Access the document service from External Applications through Proxy Bridge - Proxy Bridge

In this blog, I will explain the steps required to access  the SAP Cloud Platform Document Service from UI5/Fiori applications deployed on the SAP Cloud Platform itself.

Pre-requisites:

  1. A trial account in SAP Cloud Platform (Neo) (http://account.hanatrial.ondemand.com)

  2. Eclipse configured with SAP Cloud Platform tools for Java. Refer Set up Eclipse - This tutorial covers the steps to install SAP Cloud Platform Tools and SAP Cloud Platform SDK for Java. Please make sure that you install the SDK for Java EE 7 Web Profile TomEE 7 (from https://tools.hana.ondemand.com/#cloud ) and not the one mentioned in the tutorial.

  3. If you have not deployed a Java application to the Cloud Platform before, get yourself familiarised using the tutorial Deploying a basic Java application on SAP Cloud Platform


1. Enable the SAP Cloud Document Service in Cloud.

As with any service on SAP Cloud Platform, the first step is to enable the service in your trial subaccount.



Once you enable the service, you can manage the Document Repositories from the cockpit. Refer -managing Document Repositories in the Cockpit. We will be creating the repositories from the Java application itself for this use case.

2. Create a Java Web Service application to access the Document Service.

Create a Dynamic Web Project in Eclipse. Make sure to use the JAVA EE 7 Web as Target Runtime, The is required for JAX-RS webservices. Once the application is created, open the Web.xml and add the following resource reference.
<resource-ref>
<res-ref-name>EcmService</res-ref-name>
<res-type>com.sap.ecm.api.EcmService</res-type>
</resource-ref>



The document service is consumed by defining a resource in your web.xml file and by using JNDI lookup to retrieve an instance of the com.sap.ecm.api.EcmService class. Once you have established a connection to the document service, you can use one of theconnect(…) methods to get a CMIS session

Create a Java class - ManageDocuments with the following methods

  • getSession - This method retrieves the CMIS session for the document repository. It creates a repository, if it does not exists already.


private Session getSession() {
String uniqueName = "<<Any Name>>";
String secretKey = "<<Secret Key - provide any key>>";
Session openCmisSession = null;
EcmService ecmSvc = null;
InitialContext ctx;
try {
ctx = new InitialContext();
String lookupName = "java:comp/env/" + "EcmService";
ecmSvc = (EcmService) ctx.lookup(lookupName);

} catch (NamingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
// connect to my repository
openCmisSession = ecmSvc.connect(uniqueName, secretKey);
} catch (CmisObjectNotFoundException e) {
// repository does not exist, so try to create it
RepositoryOptions options = new RepositoryOptions();
options.setUniqueName(uniqueName);
options.setRepositoryKey(secretKey);
options.setVisibility(Visibility.PROTECTED);
ecmSvc.createRepository(options);
// should be created now, so connect to it
openCmisSession = ecmSvc.connect(uniqueName, secretKey);
}
return openCmisSession;

}


  • create - This method creates the folder and uploads the file using the information passed as JSON. This method access the getSession() to access the CMIS session.


// local classes
class result {
String message;

void setMessage(String message) {
this.message = message;
}
}
class uploadData{
String file;
String fileName;
String folderName;
void setFile(String file) {
this.file = file;
}
void setFileName(String fileName) {
this.fileName = fileName;
}
void setFolderName(String folderName) {
this.folderName = folderName;
}

}

/**
* Creates the folder and file
* @param upload
* @return
*/
@POST
@Path("/create")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(uploadData upload) {
result r = new result();
String message = "";
Session openCmisSession = getSession();
// access the root folder of the repository
Folder root = openCmisSession.getRootFolder();
// create a new folder
try {
Map<String, String> newFolderProps = new HashMap<String, String>();
newFolderProps.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
newFolderProps.put(PropertyIds.NAME, upload.folderName);
root.createFolder(newFolderProps);
message = message + "Folder "+upload.folderName + " created in root." + "\n";
} catch (CmisNameConstraintViolationException e) {
// Folder exists already, nothing to do
message = message + "Folder "+upload.folderName + " already exists." + "\n";
}

// create a new file in the folder
List<Tree<FileableCmisObject>> folderTree = root.getFolderTree(1);
Tree<FileableCmisObject> treeo = folderTree.get(0);
Folder f = (Folder)treeo.getItem();
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
try {
properties.put(PropertyIds.NAME, upload.fileName);
byte[] fileContent;
fileContent = upload.file.getBytes("UTF-8");

InputStream stream = new ByteArrayInputStream(fileContent);
ContentStream contentStream = openCmisSession.getObjectFactory().createContentStream(upload.fileName,
fileContent.length, "text/plain; charset=UTF-8", stream);

f.createDocument(properties, contentStream, VersioningState.NONE);
message = message + "File "+upload.fileName + " created under Folder " + f.getName() + ".\n";
} catch (CmisNameConstraintViolationException e) {
// Document exists already, nothing to do
message = message + "File "+upload.fileName + " already exists in the folder "+ f.getName() + ".\n";

} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
r.setMessage(e1.getMessage());
return Response.ok(r, MediaType.APPLICATION_JSON).build();


}
r.setMessage(message);
return Response.ok(r, MediaType.APPLICATION_JSON).build();
}

 

3. Deploy and test the Java Web Service application on the SAP Cloud Platform.

Once the class is ready, deploy it on the SAP cloud Platform. You can view the deployed application under 'Java applications' in the Cloud Platform Cockpit.



You can see that there are no repositories under 'Document repositories' in your trial account.



Let us test the deployed application from Postman to make sure that it can access and create the documents in the repository.

The web service requires JSON data with folder name, file name and the file contents to create them in the document repository. We can test the service by supplying these in the body of the post request. Make sure you pass the content type as 'application/json' in the request header.



I have coded the java webservice to give a confirmation of the steps completed.



Go back to the SAP Cloud Platform Cockpit and you will see the new document repository created with the name you have given in the java application.



 

4. Create a UI5/Fiori application to access the Java Web Service application.

It is a simple sales order application using the oData services provided by SAP Gateway demo server ES5. It lists the orders and order line items in a Master-Detail application.



I have added few lines of code under the attachment tab to add the file upload functionality. Before we can start with the changes, we need a destination in SAP Cloud Platform to access the java application.



Check the destination and make sure that it is reachable.

Add the view elements in view.xml to add the File upload control to the application. Open the controller file and add the following code in the action handler function which handles the upload functionality. Basically we will be sending the current sales order number for the folder name to be created.
	onHandleUploadPress: function (oEvent) {

var oFileUpload = this.getView().byId("fileUploader");
var domRef = oFileUpload.getFocusDomRef();
var file = domRef.files[0];
var that = this;
//Get the file name and type
this.fileName = file.name;
this.fileType = file.type;
//get the order number to be used as folder name
this.folderName = this.getModel("detailView").getData().sObjectId;
var reader = new FileReader();
reader.onload = function (e) {
var content = e.currentTarget.result.replace("data:" + file.type + ";base64,", "");
//call the method to make the ajax call to the webservice,
that.sendFiletoCloud(that.folderName, that.fileName, content);
};
reader.readAsDataURL(file);

},

The method below makes the Ajax call to the web service destination.
	sendFiletoCloud: function (folderName, fileName, file) {
jQuery.ajax({
url: "/clouddocumentservice/managedocuments/create",
type: "POST",
data: JSON.stringify({
folderName: folderName,
fileName: fileName,
file: file

}),
dataType: "json",
contentType: "application/json",
success: function (data) {
MessageToast.show("File uploaded successfully");
},
error: function (e) {
MessageToast.show("Error while uploading the file");
}
});
},

 

Now, let us upload a file and test.





 

We have now successfully accessed and created the documents in the repository. It is pretty easy to use CMIS API to read the contents of the repository as well. I am not covering the entire flow in this blog. I am sharing the method which I used to read the contents of the repository to check the documents uploaded.
@GET
@Path("/read")
public String getobjects() {
String returnvalue = "";
Session openCmisSession = getSession();
returnvalue = "You are connected to the repository: " + openCmisSession.getRepositoryInfo().getId() + "\n";
// access the root folder of the repository
Folder root = openCmisSession.getRootFolder();
ItemIterable<CmisObject> children = root.getChildren();
for (CmisObject o : children) {
if (o instanceof Folder) {
Folder f = (Folder)o;
returnvalue = returnvalue + "Folder Name: " + o.getName() + "\n";
ItemIterable<CmisObject> Fchildren = f.getChildren();
for (CmisObject c : Fchildren) {
if(c instanceof Document) {
Document doc = (Document) c;
returnvalue = returnvalue + "File Name: " + doc.getName() + "---" + " filesize: "
+ doc.getContentStreamLength() + " bytes"+ "\n";;
}
}

} else {
Document doc = (Document) o;
returnvalue = returnvalue + " createdBy: " + o.getCreatedBy() + " filesize: "
+ doc.getContentStreamLength() + " bytes" + "\n";;

}
}

return returnvalue;

}

We can check the document uploaded from the Ui5 application by calling the method above from Postman.



As always, please feel free to comment if you have any feedback or questions.
6 Comments
Labels in this area