Skip to Content
Technical Articles

Combine CAP (M) with Machine Learning SDK – API Part

In one of my recent fun projects, I’ve been testing out CAPM together with the SAP Cloud Machine Learning (ML) SDK to create a Face Recognition app: https://blogs.sap.com/2019/05/28/face-recognition-app/

This ML SDK integrates very well into the SAP Cloud Platform Cloud Foundry (CF). It doesn’t need a destination and has access to all ML API endpoints. It also doesn’t require an additional request for authentication. Really worth using!

There is one small remark, the ML SDK is only available for Java. This means you need to use CAPM with Java for the service layer. Not a big issue but NodeJS is very popular these days 😊

In this blog, I want to share what I have learned from using this ML SDK with CAPM in the Face Recognition app. For this, I will show how you can create a new service with CAPM that uses this ML SDK. I’m going to use the ML SDK to find a face on an image and convert it to a vector. The vector could later be used to compare faces like in the Face Recognition app.

Let’s start!

I’m using SAP Web IDE because it makes it easier to test CAPM together with the ML SDK.

First, generate a project from the following template, “SAP Cloud Platform Business Application”. (Filtering on the Cloud Foundry Environment will make it easier to find the right template.)

Fill in the name of the project:

Fill in the app id and version for the mta but also select the “Use HTML5 Application Repository”. This last check will include the approuter and appdeployer into your project.

This step of the wizard contains the configuration of the service. In this case it should be java for using the ML SDK. (At this time, it’s not yet available in NodeJS). Fill in a namespace and select the latest version of the HANA database. (Again, at the time that I’m publishing this, only HANA is available as database for CF apps)

Also enable “Enable user authentication”, we’ll need this when we want to deploy to cf. This will already include some configuration into the mta.yml for us.

 

The project structure will look like this, don’t forget to enable hidden files:

Running this project with the example code will probably end up in an error like this:

If this also happens in your version, than you need to the mta.yml and change “uaa” parameter “service-plan” from “default” to “application:

Open the “db” module and open data-model.cds. This is the place to define the datamodel of the database. The name of the entity will be used for the name of the table and all properties will represent a column.

In this example, the entity will be named “Faces” because it will be used to store the vector of a person’s face on an image. Together with the vector, it will store the name and an ID. The image property will not be used in this blog but could be used to store the path to the image of the persons face.

Code snippet:

namespace be.wl;

entity Faces {
  key ID : Integer;
  Firstname  : String;
  Lastname  : String;
  Vectors : String;
  Image:String;
}



Saving the data-model.cds will build the CDS and update the csn.json file in the service module. In case it doesn’t run the “cds build” automatically, this can be trigger manually:

The database layer is already finished! 😊

Let’s go to the service layer and expose our database entity as an API. Open “cat-service.cds” and change the example code with the names used in the database layer. Change the namespace and the name of the entity.

Don’t forget to remove “@readonly” as this service should also be used for creating faces and not only reading.

Code snippet:

using be.wl as my from '../db/data-model';


service CatalogService {
    entity Faces as projection on my.Faces;
}

Alright, the service is ready to be tested. First build the java service:

Before running, check if your CF account is still valid and configured:

Right click on your project and then project settings or in the settings of you SAP Web IDE workspace

After the build, you can run it as a Java Application

I don’t know why, but the first time it failed for me. The second time I tried running the service it worked. When it’s running, you’ll get an url in the console to test your service:

This will provide you an endpoint:

Time to implement the Machine Learning logic to convert the face of a person on an image to a vector.

This logic needs to be implemented just before saving it to the database. The service will receive a base64 string of an image which needs to be converted before saving in the database. For this, CAP has the possibility to use hook functions before each OData request.

Start by generating a file for these hook functions together with some sample code:

In the next step, Web IDE needs to know the entities that will be enhanced.

Next and finish, this will generate a Java class with sample code for each possible request

The code is using a dependency to the s4hana sdk for using Machine Learning and another one for defining the mimetype of an image. These dependencies need to be defined in pom.xml

<dependency>
	<groupId>com.sap.cloud.s4hana.services</groupId>
	<artifactId>scp-machine-learning</artifactId>
</dependency>
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpmime</artifactId>
	<version>4.5.6</version>
</dependency>

Building the srv module will download the dependencies.

 

Added a new Java class in the same package as the file with hook functions for getting the extension based on a mimetype. (found this code online)

Call this class “MimeTypesExtensions”

Full code for this Java Class can be found here: https://github.com/lemaiwo/MyCAPMAppWithML/blob/master/srv/src/main/java/be/wl/handlers/catalogservice/MimeTypesExtensions.java

 

Another Java class “MachineLearningService” which will be used for everything related to Machine Learning:

This class has several functions that are needed for communication with the Machine Learning Service. Full code can be found here: https://github.com/lemaiwo/MyCAPMAppWithML/blob/master/srv/src/main/java/be/wl/handlers/catalogservice/MachineLearningService.java

First, “base64ToBytes” will convert a base64 string of an image to an array of bytes.

“getFilePost” will use the previous function to prepare the http post request together with the image to send it to the ML SDK:

This function “getFaceVector” will send the request to the ML Service and give back the vector of the persons face.

Back in the generated class “FacesHookHandler”, the code to manipulate the incoming data before saving it in the database.

CAP will call the “beforeCreateFaces” hook function for creating a new object of the entity “Faces”. This function will contain the implementation that will call the Machine Learning Service class and update the result before it’s being saved into HANA.

This line is running the magic to manipulate the data coming from the request just before it’s being saved.

Don’t forget the java imports at the top of the file.

 

If the code has no bugs, then the build will succeed 😊

The service is ready to be tested with the Machine Learning logic. First the service needs to be restarted. Otherwise it won’t take the changes into account.

SAP Web IDE has a stop and start button in console that can be used for restarting the app:

The service can now be tested. Because the app has no ui (yet), it needs to be tested with another tool like postman.

Use the url that you see in the console and run it in postman:

A get request on the service works! But a post will not yet work. The configuration is missing a reference to the machine learning service resource. This needs to be configured in the mta.yaml file:

Add “ml-service” in the requires part of the srv module

Define the ml-service at the bottom

Now the service ready to be tested by uploading an image. There is still no ui, so the image needs to be converted to a base64 string manually. This can be done via the following website:

https://www.base64-image.de/

Upload image of James Bond as an example:

Copy the result to your clipboard

Change the type of the request in postman to “POST” and add the body like this:

If everything goes well, postman will show you the following example:

We just combined CAP together with the Machine Learning SDK to convert a base64 image string to a vector and saved it into a HANA database.

Next step? Adding a UI module 🙂

Full project is available on GitHub: https://github.com/lemaiwo/MyCAPMAppWithML

1 Comment
You must be Logged on to comment or reply to a post.