From 2599501eef9a7c7929dd46f24533759e17935ded Mon Sep 17 00:00:00 2001 From: ArthurPerry Date: Tue, 5 Dec 2023 10:26:18 -0600 Subject: [PATCH 1/3] Update documentation to reflect SAP CIS prereq --- sentiment-analysis/README.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sentiment-analysis/README.md b/sentiment-analysis/README.md index 25821149..7ac32fa2 100644 --- a/sentiment-analysis/README.md +++ b/sentiment-analysis/README.md @@ -47,15 +47,32 @@ The architecture diagram describes use case flow. - [Kubernetes tooling](../prerequisites/README.md#kubernetes) +- A namespace created with [Sidecar Injection](https://kyma-project.io/#/istio/user/02-operation-guides/operations/02-20-enable-sidecar-injection) enabled. + - [SAP Commerce Cloud environment connected to SAP BTP Kyma runtime.](https://help.sap.com/docs/BTP/65de2977205c403bbc107264b8eccf4b/83df31ad3b634c0783ced522107d2e73.html) v2011 or greater in order to use the Webhooks feature. - (Optional) [SAP Sales Cloud (Cloud for Customer) connected to SAP BTP Kyma runtime](https://help.sap.com/docs/BTP/65de2977205c403bbc107264b8eccf4b/83df31ad3b634c0783ced522107d2e73.html) if you enable the `c4cUpdateFlag` (see below) +### SAP Cloud Identity Services +The Webhook handler function by default is protected by an jwt access strategy. As of Kyma version 2.19, the Ory Oathkeeper and Ory Hydra modules for managing access to APIs has been removed. They were replaced by Istio components that provide the necessary functions. You can read more in the following blog posts and documentation: + +[SAP BTP, Kyma Runtime API Gateway future architecture based on Istio | SAP Blogs ](ttps://blogs.sap.com/2023/02/10/sap-btp-kyma-runtime-api-gateway-future-architecture-based-on-istio/) + +[SAP BTP, Kyma runtime ORY Hydra OAuth2 Client migration | SAP Blogs](https://blogs.sap.com/2023/06/06/sap-btp-kyma-runtime-ory-hydra-oauth2-client-migration/) + +[Create OpenID Connect Application for Client Credentials Flow - SAP Help Portal](https://help.sap.com/docs/identity-authentication/identity-authentication/client-cred-create-openid-connect-application-for-client-credentials-flow) + +[Configure Secrets for API Authentication - SAP Help Portal](https://help.sap.com/docs/identity-authentication/identity-authentication/auth-configure-secrets-for-api-authentication) + +- Capture the the client ID and secret from your Application Client Authentication settings in SAP Cloud Identity Services then update [webhooks.impex](commerce-impex/webhooks.impex) + +- Capture the issuer and token_endpoint for your SAP CIS tenant from `https://.well-known/openid-configuration` and update [api-access.yaml](lambdas/customer-review-webhook/k8s/api-access.yaml) for the Webhook handler function. + ## Configuration The extension requires a `Secret` named `sentiment-analysis` configured in the Kyma namespace containing the following values: -- `baseSite`: The SAP Commerce Cloud baseSite value e.g. `electronics`, required by the SAP Commerce Cloud OCC API. +- `baseSite`: The SAP Commerce Cloud baseSite value e.g. `electronics-spa`, required by the SAP Commerce Cloud OCC API. Note that due to the OCC API endpoint being used for User data, only B2C channel baseSite are supported. In order to use this extension with a B2B site, [lambdas/sentiment-analysis/handler.js](lambdas/sentiment-analysis/handler.js) must be adapted to use the relevant OCC calls for the B2B channel (i.e. `getOrgUser` instead of `users` ) - `c4cUpdateFlag`: Feature flag to enable the calls to SAP Sales Cloud to create customer and service ticket for negative reviews. If value is `true` then the feature is enabled. @@ -100,7 +117,7 @@ commerce-impex/projectdata-register-integration-object.impex See the SAP Commmerce Help topic on [Data Management with Impex](https://help.sap.com/docs/SAP_COMMERCE/d0224eca81e249cb821f2cdf45a82ace/1b6dd3451fc04c3aa8e95937e9ef2471.html?q=impex). -Add the Integration Object to the registered Kyma Destination Target using SAP Commerce Cloud Backoffice as described in **Expose Your API – Existing Destination Target** section in this [blog post](https://blogs.sap.com/2022/10/14/commerce-cloud-exposing-integration-apis-to-sap-btp-kyma-runtime-with-oauth2/) on SAP Community +Add the Integration Object to the registered Kyma Destination Target using SAP Commerce Cloud Backoffice as described in **Expose Your API – Existing Destination Target** section in this [blog post](https://blogs.sap.com/2022/10/14/commerce-cloud-exposing-integration-apis-to-sap-btp-kyma-runtime-with-oauth2/) on SAP Community. Once the Integration Object API is registered with the System in BTP and the Application in Kyma, extract the Central Application Gateway URL from the corresponding Application in Kyma and update the `gateway_url_review` value in the `sentiment-analysis` secret. ### Content Moderation Service From 6894fdcf8311976dbea5cb414bd2493430ab27d3 Mon Sep 17 00:00:00 2001 From: ArthurPerry Date: Tue, 5 Dec 2023 10:27:26 -0600 Subject: [PATCH 2/3] Remove ExposedDestionation from Impex. --- .../projectdata-register-integration-object.impex | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sentiment-analysis/commerce-impex/projectdata-register-integration-object.impex b/sentiment-analysis/commerce-impex/projectdata-register-integration-object.impex index c744bb1f..bf1c19db 100644 --- a/sentiment-analysis/commerce-impex/projectdata-register-integration-object.impex +++ b/sentiment-analysis/commerce-impex/projectdata-register-integration-object.impex @@ -31,7 +31,3 @@ UserGroup ; integrationadmingroup ; ; ; ; ; ; ; User ; + ; + ; + ; + ; + ; ; ; ; Address ; + ; + ; + ; + ; + $END_USERRIGHTS; ; ; ; ; - -## Update to the correct url and destinationTarget values -INSERT_UPDATE ExposedDestination;id[unique=true];url;endpoint(id)[unique=true];additionalProperties(key,value)[map-delimiter=|];destinationTarget(id)[default=Default_Template];active[default=true];credential(id) -;cc-customerproductreview;{ccv2.services.api.url.0}/odata2webservices/CustomerProductReview;cc-customerreview;;;;odatauser-client From 34b51d0ee4a87e82c8051db9b67540e65721784f Mon Sep 17 00:00:00 2001 From: ArthurPerry Date: Tue, 5 Dec 2023 10:27:57 -0600 Subject: [PATCH 3/3] Add logging to aid with troubleshooting. --- .../lambdas/sentiment-analysis/handler.js | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/sentiment-analysis/lambdas/sentiment-analysis/handler.js b/sentiment-analysis/lambdas/sentiment-analysis/handler.js index 686ebe0a..6ddfa009 100644 --- a/sentiment-analysis/lambdas/sentiment-analysis/handler.js +++ b/sentiment-analysis/lambdas/sentiment-analysis/handler.js @@ -131,7 +131,9 @@ async function getUserDetails(userId, isAnonymous, traceCtxHeaders) { console.log(`get user details: ${url}`); let response = await axios.get(url, { headers: traceCtxHeaders }) .catch(function (error) { - console.log('Error on getUserDetails'); + console.log('*** START Error on getUserDetails'); + logerror(error); + console.log('*** END Error on getUserDetails'); }); firstName = response.data.firstName; lastName = response.data.lastName; @@ -150,6 +152,31 @@ async function getUserDetails(userId, isAnonymous, traceCtxHeaders) { return customerDetailsC4C; } +async function logerror(error) { + if (error.response) { + // The request was made and the server responded with a status code + // that falls out of the range of 2xx + console.log('*** error.response.data'); + console.log(error.response.data); + console.log('*** error.response.status'); + console.log(error.response.status); + console.log('*** error.response.headers'); + console.log(error.response.headers); + } else if (error.request) { + // The request was made but no response was received + // `error.request` is an instance of XMLHttpRequest in the browser and an instance of + // http.ClientRequest in node.js + console.log('*** error.request'); + console.log(error.request); + } else { + // Something happened in setting up the request that triggered an Error + console.log('*** error.message'); + console.log('Error', error.message); + } + console.log('*** error.config'); + console.log(error.config); +} + // getReviewDetails() not needed since we now get the review details in the event. // This method is retained to show how to access a SAP Commerce Cloud Integration API from Kyma. async function getReviewDetails(reviewCode, traceCtxHeaders) { @@ -174,7 +201,9 @@ async function updateReview(isNegative, isRude, content, traceCtxHeaders) { let response = await axios.post(`${reviewServiceURL}`, content, { headers: traceCtxHeaders }) .catch(function (error) { - console.log('Error on updateReview:' + error); + console.log('*** Error on updateReview:' + error); + logerror(error); + console.log('*** Error on updateReview:' + error); }); }