diff --git a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/Messages.java b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/Messages.java index 4dbc9507c9..04f831b707 100644 --- a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/Messages.java +++ b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/Messages.java @@ -7,23 +7,23 @@ public final class Messages { // Exception messages public static final String ERROR_EXECUTING_REST_API_CALL = "Error occurred while executing REST API call"; - public static final String MAX_UPLOAD_SIZE_EXCEEDED = "Cannot upload file, size is bigger than the configured maximum upload size \"{0}\" bytes"; + public static final String MAX_UPLOAD_SIZE_EXCEEDED_FOR_JOB_WITH_ID = "Cannot upload file, size is bigger than the configured maximum upload size \"{0}\" bytes. Job id: {1}"; public static final String COULD_NOT_GET_FILES_0 = "Could not get files: {0}"; public static final String COULD_NOT_UPLOAD_FILE_0 = "Could not upload file: {0}"; public static final String NO_FILES_TO_UPLOAD = "Request has no files to upload!"; public static final String ACTION_0_CANNOT_BE_EXECUTED_OVER_OPERATION_1_IN_STATE_2 = "Action \"{0}\" cannot be executed over operation \"{1}\" in state \"{2}\"."; public static final String OPERATION_0_NOT_FOUND = "Operation \"{0}\" was not found."; public static final String TEMPORARY_PROBLEM_WITH_PERSISTENCE_LAYER = "Temporary problem with persistence layer of the service"; - public static final String FILE_URL_RESPONSE_DID_NOT_RETURN_CONTENT_LENGTH = "File URL response did not return Content-Length header"; - public static final String ERROR_FROM_REMOTE_MTAR_ENDPOINT = "Error from remote MTAR endpoint {0} with status code {1}, message: {2}"; - public static final String MTAR_ENDPOINT_NOT_SECURE = "Remote MTAR endpoint is not a secure connection. HTTPS required"; + public static final String FILE_URL_RESPONSE_DID_NOT_RETURN_CONTENT_LENGTH_FOR_JOB_WITH_ID = "File URL response did not return Content-Length header. Job id: {0}"; + public static final String ERROR_FROM_REMOTE_MTAR_ENDPOINT_FOR_JOB_WITH_ID = "Error from remote MTAR endpoint {0} with status code {1}, message: {2}. Job id: {3}"; + public static final String MTAR_ENDPOINT_NOT_SECURE_FOR_JOB_WITH_ID = "Remote MTAR endpoint is not a secure connection. HTTPS required. Job id: {0}"; public static final String CANNOT_PARSE_CONTAINER_URI_OF_OBJECT_STORE = "Cannot parse container_uri of object store"; public static final String REQUEST_0_1_FAILED_WITH_2 = "Request \"{0} {1}\" failed with \"{2}\""; public static final String ERROR_OCCURRED_WHILE_DELETING_JOB_ENTRY = "Error occurred while deleting job entry"; public static final String CANNOT_CREATE_OBJECT_STORE_CLIENT_WITH_PROVIDER_0 = "Cannot create Object Store client with provider: {0}"; public static final String NO_VALID_OBJECT_STORE_CONFIGURATION_FOUND = "No valid Object Store configuration found!"; public static final String MISSING_PROPERTIES_FOR_CREATING_THE_SPECIFIC_PROVIDER = "Missing properties for creating the specific provider!"; - public static final String DEPLOY_FROM_URL_WRONG_CREDENTIALS = "Credentials to {0} are wrong. Make sure that they are correct."; + public static final String DEPLOY_FROM_URL_WRONG_CREDENTIALS_FOR_JOB_WITH_ID = "Credentials to {0} are wrong. Make sure that they are correct. Job id: {1}"; public static final String JOB_NOT_UPDATED_FOR_0_SECONDS = "Job not updated for {0} seconds"; public static final String FAILED_TO_CREATE_BLOB_STORE_CONTEXT = "Failed to create BlobStoreContext"; @@ -77,11 +77,11 @@ public final class Messages { public static final String ASYNC_UPLOAD_JOB_EXISTS = "Async upload job for URL {} exists: {}"; public static final String CREATING_ASYNC_UPLOAD_JOB = "Creating async upload job for URL {} with ID: {}"; public static final String ASYNC_UPLOAD_JOB_REJECTED = "Async upload job with space guid: {}, namespace: {}, URL: {} rejected."; - public static final String STARTING_DOWNLOAD_OF_MTAR = "Starting download of MTAR from remote endpoint: {}"; - public static final String UPLOADED_MTAR_FROM_REMOTE_ENDPOINT_AND_JOB_ID = "Uploaded MTAR from remote endpoint {} with job id: {} in {} ms"; + public static final String STARTING_DOWNLOAD_OF_MTAR_WITH_JOB_ID = "Starting download of MTAR from remote endpoint: {}. Job id: {}"; + public static final String UPLOADED_MTAR_FROM_REMOTE_ENDPOINT_AND_JOB_ID = "Uploaded MTAR from remote endpoint {}. Job id: {} in {} ms"; public static final String ASYNC_UPLOAD_JOB_FINISHED = "Async upload job {} finished"; - public static final String UPLOADING_MTAR_STREAM_FROM_REMOTE_ENDPOINT = "Uploading MTAR stream from remote endpoint: {}"; - public static final String CALLING_REMOTE_MTAR_ENDPOINT = "Calling remote MTAR endpoint {}"; + public static final String UPLOADING_MTAR_STREAM_FROM_REMOTE_ENDPOINT_WITH_JOB_ID = "Uploading MTAR stream from remote endpoint: {}. Job id: {}"; + public static final String CALLING_REMOTE_MTAR_ENDPOINT_FOR_JOB_WITH_ID = "Calling remote MTAR endpoint {}. Job id: {}"; private Messages() { } diff --git a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/AsyncUploadJobOrchestrator.java b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/AsyncUploadJobOrchestrator.java index 22dd65834f..4208c14d5e 100644 --- a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/AsyncUploadJobOrchestrator.java +++ b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/AsyncUploadJobOrchestrator.java @@ -106,7 +106,7 @@ private AsyncUploadJobEntry createJobEntry(String spaceGuid, String namespace, S } private void deployFromUrl(AsyncUploadJobEntry jobEntry, String fileUrl, UserCredentials userCredentials) { - LOGGER.info(Messages.STARTING_DOWNLOAD_OF_MTAR, jobEntry.getUrl()); + LOGGER.info(Messages.STARTING_DOWNLOAD_OF_MTAR_WITH_JOB_ID, jobEntry.getUrl(), jobEntry.getId()); var startTime = LocalDateTime.now(); Lock lock = new ReentrantLock(); AtomicLong counterRef = new AtomicLong(); @@ -185,7 +185,9 @@ private FileEntry doUploadMtarFromUrl(UploadFromUrlContext uploadFromUrlContext, // JClods library: https://issues.apache.org/jira/browse/JCLOUDS-1623 try (CountingInputStream source = new CountingInputStream(fileFromUrlData.fileInputStream(), uploadFromUrlContext.getCounterRef()); BufferedInputStream bufferedContent = new BufferedInputStream(source, INPUT_STREAM_BUFFER_SIZE)) { - LOGGER.debug(Messages.UPLOADING_MTAR_STREAM_FROM_REMOTE_ENDPOINT, fileFromUrlData.uri()); + LOGGER.debug(Messages.UPLOADING_MTAR_STREAM_FROM_REMOTE_ENDPOINT_WITH_JOB_ID, fileFromUrlData.uri(), + uploadFromUrlContext.getJobEntry() + .getId()); return fileService.addFile(ImmutableFileEntry.builder() .space(uploadFromUrlContext.getJobEntry() .getSpaceGuid()) diff --git a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClient.java b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClient.java index 868ea8611c..75f714116c 100644 --- a/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClient.java +++ b/multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClient.java @@ -50,39 +50,48 @@ public DeployFromUrlRemoteClient(ApplicationConfiguration applicationConfigurati public FileFromUrlData downloadFileFromUrl(UploadFromUrlContext uploadFromUrlContext) throws Exception { if (!UriUtil.isUrlSecure(uploadFromUrlContext.getFileUrl())) { - throw new SLException(Messages.MTAR_ENDPOINT_NOT_SECURE); + throw new SLException(Messages.MTAR_ENDPOINT_NOT_SECURE_FOR_JOB_WITH_ID, uploadFromUrlContext.getJobEntry() + .getId()); } UriUtil.validateUrl(uploadFromUrlContext.getFileUrl()); HttpResponse response = callRemoteEndpointWithRetry(uploadFromUrlContext.getFileUrl(), + uploadFromUrlContext.getJobEntry() + .getId(), uploadFromUrlContext.getUserCredentials()); long fileSize = response.headers() .firstValueAsLong(Constants.CONTENT_LENGTH) - .orElseThrow(() -> new SLException(Messages.FILE_URL_RESPONSE_DID_NOT_RETURN_CONTENT_LENGTH)); + .orElseThrow(() -> new SLException( + MessageFormat.format(Messages.FILE_URL_RESPONSE_DID_NOT_RETURN_CONTENT_LENGTH_FOR_JOB_WITH_ID, + uploadFromUrlContext.getJobEntry() + .getId()))); long maxUploadSize = applicationConfiguration.getMaxUploadSize(); if (fileSize > maxUploadSize) { - throw new SLException(MessageFormat.format(Messages.MAX_UPLOAD_SIZE_EXCEEDED, maxUploadSize)); + throw new SLException(MessageFormat.format(Messages.MAX_UPLOAD_SIZE_EXCEEDED_FOR_JOB_WITH_ID, maxUploadSize, + uploadFromUrlContext.getJobEntry() + .getId())); } return new FileFromUrlData(response.body(), response.uri(), fileSize); } - private HttpResponse callRemoteEndpointWithRetry(String decodedUrl, UserCredentials userCredentials) + private HttpResponse callRemoteEndpointWithRetry(String decodedUrl, String jobId, UserCredentials userCredentials) throws Exception { return resilientOperationExecutor.execute((CheckedSupplier>) () -> { var request = buildFetchFileRequest(decodedUrl, userCredentials); - LOGGER.debug(Messages.CALLING_REMOTE_MTAR_ENDPOINT, getMaskedUri(urlDecodeUrl(decodedUrl))); + LOGGER.debug(Messages.CALLING_REMOTE_MTAR_ENDPOINT_FOR_JOB_WITH_ID, getMaskedUri(urlDecodeUrl(decodedUrl)), jobId); var response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream()); if (response.statusCode() / 100 != 2) { String error = readErrorBodyFromResponse(response); LOGGER.error(error); if (response.statusCode() == HttpStatus.UNAUTHORIZED.value()) { - String errorMessage = MessageFormat.format(Messages.DEPLOY_FROM_URL_WRONG_CREDENTIALS, - UriUtil.stripUserInfo(decodedUrl)); + String errorMessage = MessageFormat.format(Messages.DEPLOY_FROM_URL_WRONG_CREDENTIALS_FOR_JOB_WITH_ID, + UriUtil.stripUserInfo(decodedUrl), jobId); throw new SLException(errorMessage); } - throw new SLException(MessageFormat.format(Messages.ERROR_FROM_REMOTE_MTAR_ENDPOINT, getMaskedUri(urlDecodeUrl(decodedUrl)), - response.statusCode(), error)); + throw new SLException( + MessageFormat.format(Messages.ERROR_FROM_REMOTE_MTAR_ENDPOINT_FOR_JOB_WITH_ID, getMaskedUri(urlDecodeUrl(decodedUrl)), + response.statusCode(), error, jobId)); } return response; }); diff --git a/multiapps-controller-web/src/test/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClientTest.java b/multiapps-controller-web/src/test/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClientTest.java index 1611dc5976..6e6fa69ff2 100644 --- a/multiapps-controller-web/src/test/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClientTest.java +++ b/multiapps-controller-web/src/test/java/org/cloudfoundry/multiapps/controller/web/upload/client/DeployFromUrlRemoteClientTest.java @@ -14,6 +14,7 @@ import org.cloudfoundry.multiapps.controller.client.util.CheckedSupplier; import org.cloudfoundry.multiapps.controller.client.util.ResilientOperationExecutor; import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration; +import org.cloudfoundry.multiapps.controller.persistence.model.AsyncUploadJobEntry; import org.cloudfoundry.multiapps.controller.web.Constants; import org.cloudfoundry.multiapps.controller.web.Messages; import org.cloudfoundry.multiapps.controller.web.upload.UploadFromUrlContext; @@ -57,6 +58,9 @@ class DeployFromUrlRemoteClientTest { @Mock private UploadFromUrlContext uploadContext; + @Mock + private AsyncUploadJobEntry jobEntry; + private TestableDeployFromUrlRemoteClient client; private class TestableDeployFromUrlRemoteClient extends DeployFromUrlRemoteClient { @@ -89,6 +93,8 @@ void setUp() throws Exception { when(applicationConfiguration.getMaxUploadSize()).thenReturn(MAX_UPLOAD_SIZE); when(uploadContext.getFileUrl()).thenReturn(SECURE_URL); when(uploadContext.getUserCredentials()).thenReturn(userCredentials); + when(uploadContext.getJobEntry()).thenReturn(jobEntry); + when(jobEntry.getId()).thenReturn("test-job-id"); when(userCredentials.getUsername()).thenReturn("testUser"); when(userCredentials.getPassword()).thenReturn("testPassword"); } @@ -115,7 +121,7 @@ void downloadFileFromUrlInsecureUrl() { when(uploadContext.getFileUrl()).thenReturn(INSECURE_URL); Exception exception = assertThrows(SLException.class, () -> client.downloadFileFromUrl(uploadContext)); - assertEquals(Messages.MTAR_ENDPOINT_NOT_SECURE, exception.getMessage()); + assertEquals(MessageFormat.format(Messages.MTAR_ENDPOINT_NOT_SECURE_FOR_JOB_WITH_ID, "test-job-id"), exception.getMessage()); } @Test @@ -127,7 +133,7 @@ void downloadFileFromUrlNoContentLength() throws Exception { SLException exception = assertThrows(SLException.class, () -> client.downloadFileFromUrl(uploadContext)); - assertEquals(Messages.FILE_URL_RESPONSE_DID_NOT_RETURN_CONTENT_LENGTH, exception.getMessage()); + assertEquals(MessageFormat.format(Messages.FILE_URL_RESPONSE_DID_NOT_RETURN_CONTENT_LENGTH_FOR_JOB_WITH_ID, "test-job-id"), exception.getMessage()); } @@ -141,7 +147,7 @@ void downloadFileFromUrlFileSizeExceedsLimit() throws Exception { SLException exception = assertThrows(SLException.class, () -> client.downloadFileFromUrl(uploadContext)); - assertEquals(MessageFormat.format(Messages.MAX_UPLOAD_SIZE_EXCEEDED, MAX_UPLOAD_SIZE), + assertEquals(MessageFormat.format(Messages.MAX_UPLOAD_SIZE_EXCEEDED_FOR_JOB_WITH_ID, MAX_UPLOAD_SIZE, "test-job-id"), exception.getMessage()); } @@ -170,7 +176,7 @@ void callRemoteEndpointWithRetryUnauthorizedError() throws Exception { SLException exception = assertThrows(SLException.class, () -> client.downloadFileFromUrl(uploadContext)); - assertEquals("Credentials to https://example.com/file.zip are wrong. Make sure that they are correct.", exception.getMessage()); + assertEquals(MessageFormat.format(Messages.DEPLOY_FROM_URL_WRONG_CREDENTIALS_FOR_JOB_WITH_ID, "https://example.com/file.zip", "test-job-id"), exception.getMessage()); } @Test