Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
kumaramar
Advisor
Advisor
Introduction

Cloud Integration Keystore Monitor allows a tenant administrator to manage the tenant keystore and its entries. A keystore contains entries uniquely identified by an alias where each entry has its own lifecycle. Renewal of an entry is important task to be done before expiry, else it will lead to message failure for productive scenarios using specific certificates/key-pairs entries. The tenant administrator can be notified for those entries which are about to expire, so that he can take in-time actions for renewal of the same.

Within keystore monitor, expired keys and certificates are highlighted showing expiration date. In addition, an Integration Flow can be modeled to get notifications via mail for entries reaching their expiry. This document provides steps to model a scenario triggered via scheduler which looks across all entries of the tenant keystore and sends a mail with information about those entries reaching their expiry.

Scenario Description

Cloud Integration provides various REST APIs with technical protocol as Open Data Protocol (OData) with which you can access data. These APIs can be consumed via https://<tmnUrl>/api/v1 where <tmn> is the address of the tenant management node. Here we will use API for accessing keystore entries via https://<tmnUrl>/api/v1/KeystoreEntries .Overall scenario looks as below:



Create an integration flow with Start Timer Event. Using Request-Reply step call OData APIs to fetch details of the tenant keystore entries via OData receiver channel. Fetch Alias Name and ValidNotAfter for entity KeystoreEntries. Below find the configuration of OData Receiver channel:



Make sure the Page Size field value is null since entries in a keystore are not so many in numbers.

The response of the OData call will be a file containing all keystore entries with their Alias & Validity date. Now add a General Splitter step to split using XPath /KeystoreEntries/KeystoreEntry and pass split entries to a Local Integration Process.



In Local Integration Process, define a Content Modifier and store the values of keystore entry Alias and Validity Time in a header.



Additionally, add a message containing Alias & Validity Time information about keystore entry in body of Content Modifier. This message will be send via mail notification. You can choose to customize this information as per your need.



Now add a script to fetch Validity Time from header and compare with current date. Output of script shall be number of days left for Keystore entry to expire. You can find a sample code below:

     def map = message.getHeaders();

     String getCertExpirydate = map.get("CertExpiryDate");

     Date CertExpirydate = new SimpleDateFormat("yyyy-MM-dd").parse(getCertExpirydate);

     Date dateNow = new Date(System.currentTimeMillis());

     long dateDiff = CertExpirydate.getTime() - dateNow.getTime();

     def daysToExpire = TimeUnit.DAYS.convert(dateDiff, TimeUnit.MILLISECONDS);

     message.setHeader("daysToExpire", daysToExpire);

Add a router step to route those entries whose expiry is in less than defined number of days (e.g. daysToExpire < 4) and send an email to specific participants informing them about the expiry.

For the example explained above, here is router configuration screenshot:


Note: This might differ depending on the condition defined for your use-case or the variable defined either as Header/Property.
51 Comments
0 Kudos
Hello
Thanks a lot for your blog. it's perfect.
I have created the package, deploy.. and everything is green.. But I don't receive any email with the alert...
How can I verify in which part is not working properly?
kumaramar
Advisor
Advisor
0 Kudos
Hello Toni

Good to know that you were able to build and deploy the iflow. I hope you have understood that Alert mail will be generated only if there is any keystore entry reaching expiry (As per condition set) or already expired.

Can you activate tracing referring to https://blogs.sap.com/2018/03/13/troubleshooting-message-processing-in-the-cpi-web-application/ and check if there are entries for the expiry condition.

 

Thanks

Amar
0 Kudos
Hello Amar

Thanks for you helping.
I have obtained the error in Content Modifier

Error Details
org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[ID-vsa5107462-40927-1541369381630-22-5], cause: org.apache.camel.language.simple.types.SimpleParserException: expected symbol functionEnd but was eol

What does it mean?. any idea?
Thanks
kumaramar
Advisor
Advisor
0 Kudos
 

Hello Toni

Seems some issue with conversion. Can you recheck Header configuration in Content Modifier step and you are using right Type for Header defined as well as body is correct.

 

Thanks

Amar
0 Kudos
Hello Amar,

Now, I have problems with script:



Error Details








javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: script__Script.groovy: 5: unable to resolve class SimpleDateFormat @ line 5, column 28. Date CertExpirydate = new SimpleDateFormat(���yyyy-MM-dd���).parse(getCertExpirydate)







Somehting is wrong

Thanks
kumaramar
Advisor
Advisor
0 Kudos
Hello Toni

Kindly confirm if you copied the script code from above blog and pasted it. If this is the case, copy/paste sometime changes format for special characters and they are no more recognized during runtime when corresponding jars are created.

Kindly write that specific line of code and recheck.

 

Thanks

Amar

 
0 Kudos
Hello Amar,

 

No I have obtained an other error, in my script:

javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: message for class: new__Script, cause: groovy.lang.MissingPropertyException: No such property: message for class: new__Script

 

What does it means?

Thanks

Best regards
Hilmar
Advisor
Advisor
0 Kudos
Hi Amar,

any idea how to identify the certificates actually being used? Is there property/header available which tells you this?

Thanks,
Hilmar
kumaramar
Advisor
Advisor
0 Kudos
 

Hello Hilmar

Do you mean any Where-Used list for certificates/Keystore entires from the entire set. In case yes, this is not possible as of now.

Feel free to file your request to Mandy Krimmel regarding the same.

 

Warm Regards

Amar
former_member462643
Discoverer
0 Kudos
Hi Amar,

 

I am unable to open below document link you have provided,

 

https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/DEV/en-US/a617d6f37ddc43db8eeb1279662ed...

Please review & help.

 

Regards,

Deepak
former_member462643
Discoverer
0 Kudos
Hi Amar,

The error is 403:You don't have rights to view this page.

 

Regards,

Deepak
kumaramar
Advisor
Advisor
0 Kudos
 

Hello Deepak

Sorry for wrong link. Here is the correct one: https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/a617d6f37ddc43db8eeb1279662.... Can you recheck.

 

Thanks

Amar
Hilmar
Advisor
Advisor
swatik09
Explorer
0 Kudos
Hi Amar,

Can you please add more information on last content modifier which you used in local integration process.

Regards,

Swati
kumaramar
Advisor
Advisor
0 Kudos
Hello Swati

The Content Modifier used in Local integration process is to read each Certificate/Keypair and store the same in header/property. In addition use this to create body of the mail being sent to Administrator so that Administrator easily know which entry is reaching expiry and accordingly take appropriate actions for renewal of the same.

 

Amar
sumanth171
Active Participant
0 Kudos
Hello Amar,

 

While calling this Entity, I am receiving 403 Forbidden error. Do I need any additional roles to access this entity?

Regards,

Anil
kumaramar
Advisor
Advisor
0 Kudos

Hello Anil

You would need AuthGroup.Administrator role on the tenant to call the APIs or deploy a credential with a user having this role and then use this credential in your flow.

 

Thanks

Amar

swatik09
Explorer
0 Kudos
Hi Amar,

Thank you for your helpful blog, everything working fine for me. Right now with the above approach i am getting four mails if there are four items expires in same date. I am looking to send only one mail for all four expire items. Can i achieve this with help of Gather with splitter ? or can you suggest what would better approach.

Thanks,

Swati
kumaramar
Advisor
Advisor
0 Kudos
Hello Swati

Straight forward using Gather & Join would not be enough since Gather is meant for collecting data coming from multiple routes.

Easiest would be store/append certificate in SFTP and then have another flow which pulls data from SFTP and send it collectively to mail receiver.

 

Thanks

Amar
0 Kudos
Works like a charm!
0 Kudos
Hi kumar.amar ,

 

While running the script , i got the below error.


My Groovy script is as below


 

Details from Content Modifier is as below:


Could you please have a look and help me in this.

 

Thanks & Regards

Shubham
kumaramar
Advisor
Advisor
0 Kudos
Hi Shubham

Actually in my blog description, I write as:

In Local Integration Process, define a Content Modifier and store the values of keystore entry Alias and Validity Time in a header.



However you have defined Property in Content Modifier and hence you need to change your script code instead of def map = message.getHeaders(); 

to
def propertiesMap=message.getProperties();



Hope it helps !


Thanks

Amar
0 Kudos
Hi kumar.amar ,

 

Thanks for your response.

I am again receiving the below error :



Error Details








java.lang.NoSuchMethodException: No signature of method: java.lang.Long.–() is applicable for argument types: (java.lang.Long) values: [1601041902697] Possible solutions: is(java.lang.Object), or(java.lang.Number), abs(), abs(), any(), wait(long)









Could you please now help me in this.


Groovy script is not at all working.


Thanks
Shubham
kumaramar
Advisor
Advisor
0 Kudos
Hello Shubam

Kindly check someone at your end for Groovy script code. I used the below code and it works for me.

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import groovy.json.JsonSlurper;
import java.util.HashMap;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import groovy.json.JsonOutput


def Message processData(Message message) {

//Headers
def map = message.getHeaders();
String getCertExpirydate = map.get("CertExpiryDate");
Date CertExpirydate = new SimpleDateFormat("yyyy-MM-dd").parse(getCertExpirydate);
Date dateNow = new Date(System.currentTimeMillis());
long dateDiff = CertExpirydate.getTime() - dateNow.getTime();
def daysToExpire = TimeUnit.DAYS.convert(dateDiff, TimeUnit.MILLISECONDS);


message.setHeader("daysToExpire", daysToExpire);

return message;
}


 

Thanks

Amar
0 Kudos
i am getting issues with handling of long in the groovy script.

 


is there any way to resolve this??

 

Thanks
Shubham
PBhandari1
Explorer
0 Kudos
Hi shubh_9313,

Sometimes, It might occurs due to copy paste of the code, try to delete the minus(-) sign from this line and type again.

long dateDiff = CertExpirydate.getTime() – dateNow.getTime();

It will solve your issue.

Thanks,

Poushali Bhandari
PBhandari1
Explorer
0 Kudos
Hi kumar.amar,

It's a great blog.

Similarly, Is it possible to trigger the public key expiry notification from the pubring deployed as security Material in the CPI Tenant? Pubring contains around 20 public keys, We have a requirement to notify if any of the key is going to expire.

Thanks in advance,

Poushali Bhandari

 
0 Kudos
Hi ,

 

Could you please provide me with the Router conditions to be put in the router steps.

 

Thanks

Shubham
kumaramar
Advisor
Advisor
0 Kudos
Hi Poushali

Thanks for your inputs. Unfortunately this is not possible. I will inform about your requirement to my development team.

 

Thanks

Amar
harishdesai99
Explorer
Is this solution valid for cloud foundry as well. As there is no certifiacte to user mapping for cloud foundry, is there any way we can use this solution in cloud foundry tenants.
kumaramar
Advisor
Advisor
Hello Harish

Yes this is valid for getting notification for Certificates reaching expiry within the Keystore.

As anyways there is no concept of Certificate to User Mapping in Cloud Foundry, this is not a valid query as such.
0 Kudos

Hello kumar.amar,

 

does this solution work for certificates, directly deployed in iFlow? I tried CertificateUserMappings and KeystoreEntries APIs, none of them seems return certificate details, which directly deployed in iflow.

Thanks in advance.

Regards,

Deb

kumaramar
Advisor
Advisor
0 Kudos

Hello debtirtha.das 

I didn't get what you meant by certificates directly deployed in Integration Flows.

Certificates from CertificateUserMappings and KeystoreEntries are used in IFlow but actually deployed on the tenant and not in IFlow.

In case you are looking for solution to get notification of expired CertificateUserMappings, you can refer https://blogs.sap.com/2019/03/01/sap-cloud-platform-integration-automated-notification-for-client-ce... and for Keystore Entries, this blog suffice.

 

Thanks

Amar

0 Kudos
Hi Amar,

For example, if we add a client certificate in an inbound SOAP channel, I do not see that certificate added to keystore. Though I read that this is not SAP recommened process for client certificates.

kumaramar
Advisor
Advisor
0 Kudos
Hello debtirtha.das

When you do inbound authentication via Client Certificates, you add certificate in the Sender Channel and this doesn't need to be part of the CPI Keystore as such.

Only when you do outbound authentication using Client Certificates, you need to add respective Key-pair in Keystore and refer it via the alias name in the receiver channel.

Also I am not sure how does your query relates to this blog but anyways hope its clarified.

For inbound and outbound authentication, refer below blogs:

https://blogs.sap.com/2017/06/05/cloud-integration-how-to-setup-secure-http-inbound-connection-with-...

https://blogs.sap.com/2017/06/19/cloud-integration-how-to-setup-secure-outbound-http-connection-usin...

Thanks

Amar
Sheep2001
Explorer
0 Kudos
Hi,

 

I would be also intrested in the Router Conditions!

Maybe you could also add them to the blog via screenshot

 

Thanks

Patrick
kumaramar
Advisor
Advisor
Hi Patrick

I added it today.

 

Thanks

Amar

 
Sheep2001
Explorer
0 Kudos
Thanks kumar.amar I have already found an example in Mandys Blog 😉
xavisanse
Active Participant
0 Kudos
Hi people!

Nice entry Kumar. The governance from outside SAP BTP Integration Suite is a little weird. By the way, I have the doubt if this connection to the oData service consumes one of the pool of the licensed connections.

I supose that no, but I've havent any information about it. Do you know it? Have you ever had any trouble?

 

Thank you so much
0 Kudos
Hello Kumar,

I am trying to enable the notifications of expiring certificates in the Cloud Platform Integration (CPI).

I read through your blog.   When you go to create an iFLOW with "Start Timer Event", is there a particular Package or a Base Package I need to select?

Your first screen shot with the "Adapter Specific" configuration looks like it's a General OData package.   Where do I find this to get started?

 

Thanks for your help.

Hiko Watanabe

 

 
kumaramar
Advisor
Advisor
0 Kudos
Hi Xavier

Sorry I missed to see your query and only saw today. All connection here mentioned are within Cloud Integration and nothing outside BTP.

Or may be I didn't get your question. Can you give more details ?

 

Warm Regards

Amar
kumaramar
Advisor
Advisor
0 Kudos
Hello Hiko

As this is custom flows you can create the integration flow in any of your package created in your Cloud Integration tenant. And yes it uses Standard OData adapter which is part of Cloud integration feature.

To get started create an Integration Package in your design workspace of cloud integration tenant and then create an integration flow to get started.

 

Warm Regards

Amar

 
DLange
Participant
0 Kudos
Hi kumar.amar

 

first of all thanks for this helpfull blog post. Is it also possible to call this API for keystore credentials with OAuth authentification which can be provided by process integration? Then I do not have the dependencies to any user / assigned roles in this tenant.

Thanks

Best regards

DL
kumaramar
Advisor
Advisor

Hello Dominik

Yes of course instead of using Basic Auth, you can use OAuth Credential and call the APIs. Refer https://help.sap.com/docs/CLOUD_INTEGRATION/368c481cd6954bdfa5d0435479fd4eaf/20e26a837a8449c4b8b934b... for more information.

 

 

Thanks

Amar

 

DLange
Participant
0 Kudos
Hi kumar.amar

 

thanks for the hint. Access via OAuth to CPI is working fine. For me better option because we have no dependencies now between user and CPI access / roles.

 

Thanks

 

best regards

Dominik
kumaramar
Advisor
Advisor
0 Kudos
Perfect, glad that it works for you and I could help you.
sudhiryesu
Explorer
0 Kudos
Hi kumar.amar

I have consumed the OData service via "https://<tmnUrl>/api/v1/KeystoreEntries". It was working fine a week before. But now getting the below error. Please assist me to resolve this.



Error Details








com.sap.gateway.core.ip.component.odata.exception.OsciException: Attempted read from closed stream., cause: java.io.IOException: Attempted read from closed stream.



Thanks,

Sudhir Yesu



sulbhkalra
Explorer
0 Kudos
Hi kumar.amar

 

I am new to CPI.

Can you please help me how I can locate tmnUrl( Tenant Management Node URL) from my BTP account to consume Odata service from https://<tmnUrl>/api/v1/KeystoreEntries.

I also referred another blog where they mentioned "To get this tenant management URL, simply copy the initial URL from the browser address bar while you are in Cloud integration."

whereas Try Out | Security Content | SAP Business Accelerator Hub says URL should be like https://<AccountShortName>-tmn.<SSLHOST>.us1.hana.ondemand.com/api/v1.

 

Regards

Sulbh Kalra
kumaramar
Advisor
Advisor
0 Kudos
Hello Sulbh Kalra

To get value of tmnUrl for your tenant, you can refer https://help.sap.com/docs/cloud-integration/sap-cloud-integration/http-calls-and-uri-components?loca... as it clearly explains for both Neo and Cloud Foundry environemnt.

 

Warm Regards

Amar
venkat_bojjani
Explorer
0 Kudos

Hi Amar,

Thanks for the nice blog. It worked as expected.

 

Thanks

Venkat B.