Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<InputStream> 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<InputStream> callRemoteEndpointWithRetry(String decodedUrl, UserCredentials userCredentials)
private HttpResponse<InputStream> callRemoteEndpointWithRetry(String decodedUrl, String jobId, UserCredentials userCredentials)
throws Exception {
return resilientOperationExecutor.execute((CheckedSupplier<HttpResponse<InputStream>>) () -> {
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;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -57,6 +58,9 @@ class DeployFromUrlRemoteClientTest {
@Mock
private UploadFromUrlContext uploadContext;

@Mock
private AsyncUploadJobEntry jobEntry;

private TestableDeployFromUrlRemoteClient client;

private class TestableDeployFromUrlRemoteClient extends DeployFromUrlRemoteClient {
Expand Down Expand Up @@ -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");
}
Expand All @@ -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
Expand All @@ -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());

}

Expand All @@ -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());

}
Expand Down Expand Up @@ -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
Expand Down
Loading