-
Notifications
You must be signed in to change notification settings - Fork 9
Error handling fix #320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error handling fix #320
Changes from all commits
f30e5a9
1c2eab8
059cd5a
70dab64
6f7ab1b
5b44e91
6a03360
973e70c
43dfa3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,8 @@ | |
| import com.sap.cloud.security.config.ClientCredentials; | ||
| import java.io.IOException; | ||
| import java.io.UnsupportedEncodingException; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import org.apache.http.client.HttpClient; | ||
| import org.apache.http.client.methods.CloseableHttpResponse; | ||
| import org.apache.http.client.methods.HttpDelete; | ||
|
|
@@ -35,50 +37,147 @@ public class SDMAdminServiceImpl implements SDMAdminService { | |
| @java.lang.Override | ||
| public String onboardRepository(Repository repository) | ||
| throws JsonProcessingException, UnsupportedEncodingException { | ||
| SDMCredentials sdmCredentials = tokenHandler.getSDMCredentials(); | ||
| var httpClient = | ||
| tokenHandler.getHttpClient( | ||
| null, null, repository.getSubdomain(), "TECHNICAL_CREDENTIALS_FLOW"); | ||
| if (repository == null) { | ||
| logger.error("Repository object is null. Cannot proceed with onboarding."); | ||
| throw new IllegalArgumentException("Repository object cannot be null."); | ||
| } | ||
|
|
||
| SDMCredentials sdmCredentials; | ||
| try { | ||
| sdmCredentials = tokenHandler.getSDMCredentials(); | ||
| if (sdmCredentials == null || sdmCredentials.getUrl() == null) { | ||
| logger.error("SDM credentials are missing or invalid."); | ||
| throw new ServiceException("SDM credentials are missing or invalid."); | ||
| } | ||
| } catch (Exception e) { | ||
| logger.error("Failed to retrieve SDM credentials: " + e.getMessage()); | ||
| throw new ServiceException("Failed to retrieve SDM credentials.", e); | ||
| } | ||
|
|
||
| HttpClient httpClient = null; | ||
| try { | ||
| httpClient = | ||
| tokenHandler.getHttpClient( | ||
| null, null, repository.getSubdomain(), "TECHNICAL_CREDENTIALS_FLOW"); | ||
| if (httpClient == null) { | ||
| logger.error("Failed to create HTTP client."); | ||
| throw new ServiceException("Failed to create HTTP client."); | ||
| } | ||
| } catch (Exception e) { | ||
| logger.error("Error while creating HTTP client: " + e.getMessage()); | ||
| throw new ServiceException("Error while creating HTTP client.", e); | ||
| } | ||
|
|
||
| String sdmUrl = sdmCredentials.getUrl() + SDMConstants.REST_V2_REPOSITORIES; | ||
| HttpPost onboardingReq = new HttpPost(sdmUrl); | ||
| ObjectMapper objectMapper = new ObjectMapper(); | ||
| RepositoryBody onboardRepository = new RepositoryBody(); | ||
| repository.setExternalId(REPOSITORY_ID); | ||
| onboardRepository.setRepository(repository); | ||
| String json = objectMapper.writeValueAsString(onboardRepository); | ||
| StringEntity entity = new StringEntity(json); | ||
|
|
||
| try { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we have a single try and multiple catch blocks instead of multiple try
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure |
||
| repository.setExternalId(REPOSITORY_ID); | ||
| onboardRepository.setRepository(repository); | ||
| } catch (Exception e) { | ||
| logger.error("Failed to set repository details: " + e.getMessage()); | ||
| throw new ServiceException("Failed to set repository details.", e); | ||
| } | ||
|
|
||
| String json; | ||
| try { | ||
| json = objectMapper.writeValueAsString(onboardRepository); | ||
| } catch (JsonProcessingException e) { | ||
| logger.error("Failed to serialize repository object to JSON: " + e.getMessage()); | ||
| throw new ServiceException("Failed to serialize repository object to JSON.", e); | ||
| } | ||
|
|
||
| StringEntity entity; | ||
| try { | ||
| entity = new StringEntity(json); | ||
| } catch (UnsupportedEncodingException e) { | ||
| logger.error("Failed to create StringEntity: " + e.getMessage()); | ||
| throw new ServiceException("Failed to create StringEntity.", e); | ||
| } | ||
|
|
||
| onboardingReq.setEntity(entity); | ||
| // Set the content type of the request | ||
| onboardingReq.setHeader("Content-Type", "application/json"); | ||
|
|
||
| try (var response = (CloseableHttpResponse) httpClient.execute(onboardingReq)) { | ||
| String responseString = EntityUtils.toString(response.getEntity()); | ||
|
|
||
| if ((responseString.contains(REPOSITORY_ID + " already exists")) | ||
| && response.getStatusLine().getStatusCode() == 409) { | ||
| return String.format( | ||
| SDMConstants.REPOSITORY_ALREADY_EXIST, repository.getDisplayName(), REPOSITORY_ID); | ||
| } | ||
| JsonObject jsonObject = JsonParser.parseString(responseString).getAsJsonObject(); | ||
| String repositoryId = jsonObject.get("id").getAsString(); | ||
|
|
||
| JsonObject jsonObject; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we test update subscription flow as well |
||
| jsonObject = JsonParser.parseString(responseString).getAsJsonObject(); | ||
|
|
||
| String repositoryId; | ||
| if (jsonObject.has("id") && !jsonObject.get("id").isJsonNull()) { | ||
| repositoryId = jsonObject.get("id").getAsString(); | ||
| } else { | ||
| logger.error( | ||
| String.format(SDMConstants.ONBOARD_REPO_ERROR_MESSAGE, repository.getDisplayName()) | ||
| + " : " | ||
| + responseString); | ||
| throw new ServiceException( | ||
| String.format(SDMConstants.ONBOARD_REPO_ERROR_MESSAGE, repository.getDisplayName()), | ||
| responseString); | ||
| } | ||
|
|
||
| return String.format( | ||
| SDMConstants.ONBOARD_REPO_MESSAGE, repository.getDisplayName(), repositoryId); | ||
| } catch (IOException e) { | ||
| } catch (Exception e) { | ||
| logger.error( | ||
| String.format(SDMConstants.ONBOARD_REPO_ERROR_MESSAGE, repository.getDisplayName()) | ||
| + " : " | ||
| + e.getMessage()); | ||
| throw new ServiceException( | ||
| String.format(SDMConstants.ONBOARD_REPO_ERROR_MESSAGE, repository.getDisplayName()), | ||
| e.getMessage()); | ||
| String.format(SDMConstants.ONBOARD_REPO_ERROR_MESSAGE, repository.getDisplayName()), e); | ||
| } | ||
| } | ||
|
|
||
| @java.lang.Override | ||
| public String offboardRepository(String subdomain) { | ||
| SDMCredentials sdmCredentials = tokenHandler.getSDMCredentials(); | ||
| ClientCredentials clientCredentials = | ||
| new ClientCredentials(sdmCredentials.getClientId(), sdmCredentials.getClientSecret()); | ||
| SDMCredentials sdmCredentials; | ||
| try { | ||
| sdmCredentials = tokenHandler.getSDMCredentials(); | ||
| if (sdmCredentials == null | ||
| || sdmCredentials.getUrl() == null | ||
| || sdmCredentials.getBaseTokenUrl() == null) { | ||
| logger.error("SDM credentials are missing or invalid."); | ||
| throw new ServiceException("SDM credentials are missing or invalid."); | ||
| } | ||
| } catch (Exception e) { | ||
| logger.error("Failed to retrieve SDM credentials: " + e.getMessage()); | ||
| throw new ServiceException("Failed to retrieve SDM credentials.", e); | ||
| } | ||
|
|
||
| ClientCredentials clientCredentials; | ||
| try { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we have a single try and multiple catch blocks? this improves performance, better error handling easy maintainence
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure |
||
| clientCredentials = | ||
| new ClientCredentials(sdmCredentials.getClientId(), sdmCredentials.getClientSecret()); | ||
| if (clientCredentials.getId() == null || clientCredentials.getSecret() == null) { | ||
| logger.error("Client credentials are missing or invalid."); | ||
| throw new ServiceException("Client credentials are missing or invalid."); | ||
| } | ||
| } catch (Exception e) { | ||
| logger.error("Failed to create client credentials: " + e.getMessage()); | ||
| throw new ServiceException("Failed to create client credentials.", e); | ||
| } | ||
|
|
||
| String baseTokenUrl = sdmCredentials.getBaseTokenUrl(); | ||
| if (subdomain != null && !subdomain.equals("")) { | ||
| String providersubdomain = | ||
| baseTokenUrl.substring(baseTokenUrl.indexOf("/") + 2, baseTokenUrl.indexOf(".")); | ||
| baseTokenUrl = baseTokenUrl.replace(providersubdomain, subdomain); | ||
| if (subdomain != null && !subdomain.isEmpty()) { | ||
| try { | ||
| String providersubdomain = | ||
| baseTokenUrl.substring(baseTokenUrl.indexOf("/") + 2, baseTokenUrl.indexOf(".")); | ||
| baseTokenUrl = baseTokenUrl.replace(providersubdomain, subdomain); | ||
| } catch (Exception e) { | ||
| logger.error("Failed to replace subdomain in base token URL: " + e.getMessage()); | ||
| throw new ServiceException("Failed to replace subdomain in base token URL.", e); | ||
| } | ||
| } | ||
|
|
||
| var destination = | ||
| OAuth2DestinationBuilder.forTargetUrl(sdmCredentials.getUrl()) | ||
| .withTokenEndpoint(baseTokenUrl) | ||
|
|
@@ -92,44 +191,84 @@ public String offboardRepository(String subdomain) { | |
| builder.maxConnectionsPerRoute(SDMConstants.MAX_CONNECTIONS_PER_ROUTE); | ||
| builder.maxConnectionsTotal(SDMConstants.MAX_CONNECTIONS_TOTAL); | ||
| DefaultHttpClientFactory factory = builder.build(); | ||
| HttpClient httpClient = factory.createHttpClient(destination); | ||
| HttpClient httpClient; | ||
| try { | ||
| httpClient = factory.createHttpClient(destination); | ||
| if (httpClient == null) { | ||
| logger.error("Failed to create HTTP client."); | ||
| throw new ServiceException("Failed to create HTTP client."); | ||
| } | ||
| } catch (Exception e) { | ||
| logger.error("Error while creating HTTP client: " + e.getMessage()); | ||
| throw new ServiceException("Error while creating HTTP client.", e); | ||
| } | ||
|
|
||
| String sdmUrl = sdmCredentials.getUrl() + SDMConstants.REST_V2_REPOSITORIES + "/"; | ||
| HttpGet getRepos = new HttpGet(sdmUrl); | ||
| String repoId = ""; | ||
| try (var response = (CloseableHttpResponse) httpClient.execute(getRepos)) { | ||
| repoId = getRepositoryId(EntityUtils.toString(response.getEntity())); | ||
| String responseString = EntityUtils.toString(response.getEntity()); | ||
| repoId = getRepositoryId(responseString); | ||
| if (repoId == null || repoId.isEmpty()) { | ||
| logger.error("Repository ID not found"); | ||
| return "Repository with ID " + SDMConstants.REPOSITORY_ID + " not found."; | ||
| } | ||
| } catch (IOException e) { | ||
| logger.error("Error in offboarding repository : " + e.getMessage()); | ||
| throw new ServiceException("Error in offboarding ", e.getMessage()); | ||
| logger.error("Error while fetching repository ID: " + e.getMessage()); | ||
| throw new ServiceException("Error while fetching repository ID.", e); | ||
| } catch (Exception e) { | ||
| logger.error("Unexpected error while fetching repository ID: " + e.getMessage()); | ||
| throw new ServiceException("Unexpected error while fetching repository ID.", e); | ||
rishikunnath2747 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| sdmUrl = sdmCredentials.getUrl() + SDMConstants.REST_V2_REPOSITORIES + "/" + repoId; | ||
| HttpDelete offboardingReq = new HttpDelete(sdmUrl); | ||
| // Set the content type of the request | ||
| offboardingReq.setHeader("Content-Type", "application/json"); | ||
| try (var response = (CloseableHttpResponse) httpClient.execute(offboardingReq)) { | ||
| logger.info("Repository <" + REPOSITORY_ID + "> Offboarded"); | ||
| return "Repository <" + REPOSITORY_ID + "> Offboarded"; | ||
| int statusCode = response.getStatusLine().getStatusCode(); | ||
| String responseString = EntityUtils.toString(response.getEntity()); | ||
|
|
||
| if (statusCode != 200) { // Failed to offboard | ||
| if (statusCode == 404) { // Exception isn't thrown in case of missing repository | ||
| logger.warn("Repository with ID " + SDMConstants.REPOSITORY_ID + " not found."); | ||
rishikunnath2747 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return "Repository with ID " + SDMConstants.REPOSITORY_ID + " not found."; | ||
| } | ||
| logger.error("Failed to offboard repository : " + responseString); | ||
| throw new ServiceException("Failed to offboard repository.", responseString); | ||
| } | ||
|
|
||
| logger.info("Repository " + repoId + " Offboarded"); | ||
| return "Repository " + repoId + " Offboarded"; | ||
| } catch (IOException e) { | ||
| logger.error("Error in offboarding repository : " + e.getMessage()); | ||
| throw new ServiceException("Error in offboarding ", e.getMessage()); | ||
| logger.error("Error while offboarding repository: " + e.getMessage()); | ||
| throw new ServiceException("Error while offboarding repository.", e); | ||
| } catch (Exception e) { | ||
| logger.error("Unexpected error while offboarding repository: " + e.getMessage()); | ||
| throw new ServiceException("Unexpected error while offboarding repository.", e); | ||
rishikunnath2747 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| private String getRepositoryId(String jsonString) { | ||
| ObjectMapper objectMapper = new ObjectMapper(); | ||
| try { | ||
| JsonNode rootNode = objectMapper.readTree(jsonString); | ||
| JsonNode repoInfos = rootNode.path("repoAndConnectionInfos"); | ||
| JsonNode repoInfosNode = rootNode.path("repoAndConnectionInfos"); | ||
|
|
||
| List<JsonNode> repoInfos = new ArrayList<>(); | ||
| if (repoInfosNode.isArray()) { | ||
| repoInfosNode.forEach(repoInfos::add); | ||
| } else if (!repoInfosNode.isMissingNode() && !repoInfosNode.isNull()) { | ||
| repoInfos.add(repoInfosNode); // wrap single object in a list | ||
| } | ||
|
|
||
| // Iterate through the array to find the correct externalId and retrieve the id | ||
| for (JsonNode repoInfo : repoInfos) { | ||
| JsonNode repository = repoInfo.path("repository"); | ||
| if (repository.path("externalId").asText().equals(SDMConstants.REPOSITORY_ID)) { | ||
| return repository.path("id").asText(); | ||
| } | ||
| } | ||
| } catch (Exception e) { | ||
| throw new ServiceException(String.format(e.getMessage())); | ||
| throw new ServiceException("Failed to parse repository response", e); | ||
rishikunnath2747 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| return null; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.