From 3a5f03fbdf693dff703a910ed87fcb19f83ac85a Mon Sep 17 00:00:00 2001 From: GordeaS Date: Mon, 19 Feb 2024 17:08:54 +0100 Subject: [PATCH] improved submission of EuropeanaOrgIds #EA-3720 --- .../web/service/EntityRecordService.java | 3 + .../zoho/ZohoAccessClient.java | 217 ++++++++---------- 2 files changed, 99 insertions(+), 121 deletions(-) diff --git a/entity-management-web/src/main/java/eu/europeana/entitymanagement/web/service/EntityRecordService.java b/entity-management-web/src/main/java/eu/europeana/entitymanagement/web/service/EntityRecordService.java index eb642ba5..b4339d5e 100644 --- a/entity-management-web/src/main/java/eu/europeana/entitymanagement/web/service/EntityRecordService.java +++ b/entity-management-web/src/main/java/eu/europeana/entitymanagement/web/service/EntityRecordService.java @@ -1461,6 +1461,9 @@ void updateEuropeanaIDFieldInZoho(String zohoOrganizationUrl, String europeanaId try { zohoConfiguration.getZohoAccessClient().updateZohoRecordOrganizationStringField( zohoOrganizationUrl, ZohoConstants.EUROPEANA_ID_FIELD, europeanaId); + if(logger.isDebugEnabled()) { + logger.debug("Updated organization id in Zoho got organization: {} - {}", zohoOrganizationUrl, europeanaId); + } } catch (ZohoException e) { String message = "Updating EuropeanaID field in Zoho faild for Organization: " + zohoOrganizationUrl; diff --git a/entity-management-zoho/src/main/java/eu/europeana/entitymanagement/zoho/ZohoAccessClient.java b/entity-management-zoho/src/main/java/eu/europeana/entitymanagement/zoho/ZohoAccessClient.java index c5291e9a..aaefc96b 100644 --- a/entity-management-zoho/src/main/java/eu/europeana/entitymanagement/zoho/ZohoAccessClient.java +++ b/entity-management-zoho/src/main/java/eu/europeana/entitymanagement/zoho/ZohoAccessClient.java @@ -55,14 +55,16 @@ public class ZohoAccessClient { /** * Constructor with all parameters. * - *

It will try to initialize the connection with the Zoho service. Uses the grant token for the - * initial setup with {@link Initializer#initialize(UserSignature, Environment, Token, TokenStore, - * SDKConfig, String)}. This process does NOT generate any refresh/access tokens. A call to - * one of the methods that accesses Zoho should be used after creation of an instance of this - * class to generate refresh/access tokens using the provided grant token(grant tokens have a very - * short TTL that is imposed when the grant token is requested from the Zoho api console web - * page). If the grant token was already used once before, then an extra call is not required and - * the refresh and/or access tokens should be already present in the token store. + *

+ * It will try to initialize the connection with the Zoho service. Uses the grant token for the + * initial setup with + * {@link Initializer#initialize(UserSignature, Environment, Token, TokenStore, SDKConfig, String)}. + * This process does NOT generate any refresh/access tokens. A call to one of the methods + * that accesses Zoho should be used after creation of an instance of this class to generate + * refresh/access tokens using the provided grant token(grant tokens have a very short TTL that is + * imposed when the grant token is requested from the Zoho api console web page). If the grant + * token was already used once before, then an extra call is not required and the refresh and/or + * access tokens should be already present in the token store. * * @param tokenStore the token store to be used * @param zohoEmail the zoho email @@ -71,26 +73,20 @@ public class ZohoAccessClient { * @param refreshToken the zoho initial refresh token * @param redirectUrl the registered zoho redirect url */ - public ZohoAccessClient( - TokenStore tokenStore, - String zohoEmail, - String clientId, - String clientSecret, - String refreshToken, - String redirectUrl) - throws ZohoException { + public ZohoAccessClient(TokenStore tokenStore, String zohoEmail, String clientId, + String clientSecret, String refreshToken, String redirectUrl) throws ZohoException { try { UserSignature userSignature = new UserSignature(zohoEmail); Token token = new OAuthToken(clientId, clientSecret, refreshToken, TokenType.REFRESH, redirectUrl); SDKConfig sdkConfig = new SDKConfig.Builder().setAutoRefreshFields(false).setPickListValidation(true).build(); - //Environment environment = USDataCenter.PRODUCTION; + // Environment environment = USDataCenter.PRODUCTION; Environment environment = EUDataCenter.PRODUCTION; String resourcePath = SystemUtils.getUserHome().getAbsolutePath(); // Does not generate any tokens, we'll need to execute a command to do so - Initializer.initialize( - userSignature, environment, token, tokenStore, sdkConfig, resourcePath); + Initializer.initialize(userSignature, environment, token, tokenStore, sdkConfig, + resourcePath); } catch (SDKException e) { throw new ZohoException("Error initializing ZohoAccessClient", e); } @@ -98,6 +94,7 @@ public ZohoAccessClient( /** * Retrieve Zoho Organization by its zoho URL + * * @param zohoUrl the zoho url for the Organization * @return the retrieved zoho records * @throws ZohoException wrapping the original SDK exception @@ -107,13 +104,9 @@ public Optional getZohoRecordOrganizationById(String zohoUrl) throws Zoh try { RecordOperations recordOperations = new RecordOperations(); ParameterMap paramInstance = new ParameterMap(); - paramInstance.add( - SearchRecordsParam.CRITERIA, - String.format( - ZohoConstants.ZOHO_OPERATION_FORMAT_STRING, - ZohoConstants.ID_FIELD, - ZohoConstants.EQUALS_OPERATION, - zohoId)); + paramInstance.add(SearchRecordsParam.CRITERIA, + String.format(ZohoConstants.ZOHO_OPERATION_FORMAT_STRING, ZohoConstants.ID_FIELD, + ZohoConstants.EQUALS_OPERATION, zohoId)); APIResponse response = recordOperations.searchRecords(ZohoConstants.ACCOUNTS_MODULE_NAME, paramInstance); @@ -122,23 +115,27 @@ public Optional getZohoRecordOrganizationById(String zohoUrl) throws Zoh throw new ZohoException("Zoho search organization by organization id threw an exception", e); } } - + /** * Method for updating one field in zoho + * * @param zohoUrl the URL of the organization in Zoho * @param fieldName the name of the field to update - * @param fieldValue the new value + * @param fieldValue the new value * @throws ZohoException wrapping the original SDK exception */ - public void updateZohoRecordOrganizationStringField(String zohoUrl, String fieldName, String fieldValue) throws ZohoException { + public void updateZohoRecordOrganizationStringField(String zohoUrl, String fieldName, + String fieldValue) throws ZohoException { String zohoId = EntityRecordUtils.getIdFromUrl(zohoUrl); try { RecordOperations recordOperations = new RecordOperations(); BodyWrapper request = buildUpdateRequest(fieldName, fieldValue); - - //Call updateRecord method that takes recordId, ModuleAPIName and BodyWrapper instance as parameter. - APIResponse response = recordOperations.updateRecord(Long.valueOf(zohoId), ZohoConstants.ACCOUNTS_MODULE_NAME, request); - //check if the update was successful + + // Call updateRecord method that takes recordId, ModuleAPIName and BodyWrapper instance as + // parameter. + APIResponse response = recordOperations.updateRecord(Long.valueOf(zohoId), + ZohoConstants.ACCOUNTS_MODULE_NAME, request); + // check if the update was successful validateZohoUpdateResponse(response); } catch (SDKException e) { throw new ZohoException("Zoho update the organization field threw an exception.", e); @@ -147,77 +144,68 @@ public void updateZohoRecordOrganizationStringField(String zohoUrl, String field BodyWrapper buildUpdateRequest(String fieldName, String fieldValue) { BodyWrapper request = new BodyWrapper(); - List records = new ArrayList (); + List records = new ArrayList(); Record record1 = new Record(); record1.addKeyValue(fieldName, fieldValue); records.add(record1); request.setData(records); - List trigger = new ArrayList (); - trigger.add("approval"); - trigger.add("workflow"); - trigger.add("blueprint"); - request.setTrigger(trigger); return request; } /** * Source: https://www.zoho.com/crm/developer/docs/java-sdk/v2/record-samples.html - * @throws ZohoException + * + * @throws ZohoException */ - private void validateZohoUpdateResponse(APIResponse response) throws ZohoException { - if(response != null) - { - //Get the status code from response (response.getStatusCode()) - //Check if expected response is received - if(response.isExpected()) - { - //Get object from response - ActionHandler actionHandler = response.getObject(); - if(actionHandler instanceof ActionWrapper) - { - //Get the received ResponseWrapper instance - ActionWrapper actionWrapper = (ActionWrapper) actionHandler; - //Get the list of obtained ActionResponse instances - List actionResponses = actionWrapper.getData(); - for(ActionResponse actionResponse : actionResponses) - { - //Check if the request is successful - if(actionResponse instanceof SuccessResponse) - { - //Get the received SuccessResponse instance - // SuccessResponse successResponse = (SuccessResponse)actionResponse; - // status, code, and message can be taken with: successResponse.getStatus().getValue(), successResponse.getCode().getValue(), and successResponse.getMessage().getValue() - continue; - } - //Check if the request returned an exception - else if(actionResponse instanceof APIException) - { - //Get the received APIException instance - String message = extractErrorMessage((APIException)actionResponse); - throw new ZohoException(message); - } - } - } - //Check if the request returned an exception - else if(actionHandler instanceof APIException) - { - //Get the received APIException instance - APIException exception = (APIException) actionHandler; - String message = extractErrorMessage(exception); - throw new ZohoException(message); - } + private void validateZohoUpdateResponse(APIResponse response) + throws ZohoException { + if (response == null || !response.isExpected()) { + // response is expected, if empty the update operation is not confirmed + throw new ZohoException( + "Unexpected response during updating a field in Zoho." + response.getStatusCode() + response.getObject()); + } else { + // Get object from response + ActionHandler actionHandler = response.getObject(); + if (actionHandler instanceof APIException) { + // Convert api errors to ZohoExceptions Check if the request returned an exception + throw new ZohoException(extractErrorMessage((APIException) actionHandler)); + } else if (actionHandler instanceof ActionWrapper) { + verifyZohoConfirmationResponse(actionHandler); + } + } + } + + void verifyZohoConfirmationResponse(ActionHandler actionHandler) throws ZohoException { + // Get the received ResponseWrapper instance + ActionWrapper actionWrapper = (ActionWrapper) actionHandler; + // Get the list of obtained ActionResponse instances + List actionResponses = actionWrapper.getData(); + for (ActionResponse actionResponse : actionResponses) { + // Check if the request is successful + if (actionResponse instanceof SuccessResponse) { + // Get the received SuccessResponse instance + // SuccessResponse successResponse = (SuccessResponse)actionResponse; + // status, code, and message can be taken with: successResponse.getStatus().getValue(), + // successResponse.getCode().getValue(), and successResponse.getMessage().getValue() + continue; } - else - {//If response is not as expected - throw new ZohoException("Unexpected response during updating a field in Zoho." + response.getStatusCode()); + // Check if the request returned an exception + else if (actionResponse instanceof APIException) { + // Get the received APIException instance + String message = extractErrorMessage((APIException) actionResponse); + throw new ZohoException(message); + } else { + // + throw new ZohoException("Cannot process Zoho API Response, unknown response type: " + actionResponse); } + } - } String extractErrorMessage(APIException errorResponse) { - String message = "Exeption during updating a field in Zoho. Status: " + errorResponse.getStatus().getValue() + - ", code: " + errorResponse.getCode().getValue() + ", message: " + errorResponse.getMessage().getValue(); + String message = "Exeption during updating a field in Zoho. Status: " + + errorResponse.getStatus().getValue() + ", code: " + errorResponse.getCode().getValue() + + ", message: " + errorResponse.getMessage().getValue(); return message; } @@ -230,12 +218,11 @@ String extractErrorMessage(APIException errorResponse) { * @return the list of Zoho Records (Organizations) * @throws ZohoException if an error occurred during accessing Zoho */ - public List getZcrmRecordOrganizations( - int page, int pageSize, OffsetDateTime modifiedDate) throws ZohoException { + public List getZcrmRecordOrganizations(int page, int pageSize, + OffsetDateTime modifiedDate) throws ZohoException { if (page < 1 || pageSize < 1) { - throw new ZohoException( - "Invalid page or pageSize index. Index must be >= 1", + throw new ZohoException("Invalid page or pageSize index. Index must be >= 1", new IllegalArgumentException( String.format("Provided page: %s, and pageSize: %s", page, pageSize))); } @@ -248,9 +235,8 @@ public List getZcrmRecordOrganizations( paramInstance.add(GetRecordsParam.PER_PAGE, pageSize); HeaderMap headerInstance = new HeaderMap(); headerInstance.add(GetRecordsHeader.IF_MODIFIED_SINCE, modifiedDate); - response = - recordOperations.getRecords( - ZohoConstants.ACCOUNTS_MODULE_NAME, paramInstance, headerInstance); + response = recordOperations.getRecords(ZohoConstants.ACCOUNTS_MODULE_NAME, paramInstance, + headerInstance); return getZohoRecords(response); } catch (SDKException e) { @@ -265,9 +251,9 @@ public List getZcrmRecordOrganizations( * "(field1:equals:valueA)OR(field1:equals:valueB)OR(field2:equals:valueC)" or "". * * @param searchCriteria the search criteria map provided, values can be comma separated per key - * @param criteriaOperator the criteriaOperator used for each parameter, can be one of {@link - * ZohoConstants#EQUALS_OPERATION},{@link ZohoConstants#STARTS_WITH_OPERATION}. If not - * provided or wrong value, it will default to {@link ZohoConstants#EQUALS_OPERATION}. + * @param criteriaOperator the criteriaOperator used for each parameter, can be one of + * {@link ZohoConstants#EQUALS_OPERATION},{@link ZohoConstants#STARTS_WITH_OPERATION}. If + * not provided or wrong value, it will default to {@link ZohoConstants#EQUALS_OPERATION}. * @return the created criteria in the format Zoho accepts */ String createZohoCriteriaString(Map searchCriteria, String criteriaOperator) { @@ -283,17 +269,10 @@ String createZohoCriteriaString(Map searchCriteria, String crite String finalCriteriaOperator = criteriaOperator; return searchCriteria.entrySet().stream() - .map( - entry -> - Arrays.stream(entry.getValue().split(ZohoConstants.DELIMITER_COMMA)) - .map( - value -> - String.format( - ZohoConstants.ZOHO_OPERATION_FORMAT_STRING, - entry.getKey(), - finalCriteriaOperator, - value.trim())) - .collect(Collectors.joining(ZohoConstants.OR))) + .map(entry -> Arrays.stream(entry.getValue().split(ZohoConstants.DELIMITER_COMMA)) + .map(value -> String.format(ZohoConstants.ZOHO_OPERATION_FORMAT_STRING, entry.getKey(), + finalCriteriaOperator, value.trim())) + .collect(Collectors.joining(ZohoConstants.OR))) .collect(Collectors.joining(ZohoConstants.OR)); } @@ -302,15 +281,14 @@ String createZohoCriteriaString(Map searchCriteria, String crite * * @param modifiedSince * @param startPage The number of the item from which the paging should start. First item is at - * number 1. Uses default number of items per page. + * number 1. Uses default number of items per page. * @return the list of deleted Zoho Organizations * @throws ZohoException if an error occurred during accessing Zoho */ - public List getZohoDeletedRecordOrganizations( - OffsetDateTime modifiedSince, int startPage, int pageSize) throws ZohoException { + public List getZohoDeletedRecordOrganizations(OffsetDateTime modifiedSince, + int startPage, int pageSize) throws ZohoException { if (startPage < 1) { - throw new ZohoException( - "Invalid start page index. Index must be >= 1", + throw new ZohoException("Invalid start page index. Index must be >= 1", new IllegalArgumentException("start page: " + startPage)); } try { @@ -323,9 +301,8 @@ public List getZohoDeletedRecordOrganizations( if (modifiedSince != null) { headersMap.add(GetRecordsHeader.IF_MODIFIED_SINCE, modifiedSince); } - APIResponse response = - recordOperations.getDeletedRecords( - ZohoConstants.ACCOUNTS_MODULE_NAME, paramInstance, headersMap); + APIResponse response = recordOperations + .getDeletedRecords(ZohoConstants.ACCOUNTS_MODULE_NAME, paramInstance, headersMap); return getZohoDeletedRecords(response); } catch (SDKException e) { throw new ZohoException("Cannot get deleted organization list from: " + startPage, e); @@ -371,10 +348,8 @@ public static List getZohoRecords(APIResponse response) if (response.getStatusCode() >= FIRST_ERROR_CODE) { // handle error responses if (LOGGER.isDebugEnabled()) { - LOGGER.debug( - "Zoho Error. Response Status: {}, response Headers:{}", - response.getStatusCode(), - response.getHeaders()); + LOGGER.debug("Zoho Error. Response Status: {}, response Headers:{}", + response.getStatusCode(), response.getHeaders()); } throw new ZohoException("Zoho access error. Response code: " + response.getStatusCode()); }