use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class SetupHandler method handleImportSetup.
private DataTransferResponse handleImportSetup(Headers headers, PortabilityJob job, UUID jobId) throws IOException {
String exportAuthCookie = ReferenceApiUtils.getCookie(headers, JsonKeys.EXPORT_AUTH_DATA_COOKIE_KEY);
Preconditions.checkArgument(!Strings.isNullOrEmpty(exportAuthCookie), "Export auth cookie required");
// Initial auth flow url
AuthDataGenerator generator = registry.getAuthDataGenerator(job.importService(), job.transferDataType(), AuthMode.IMPORT);
Preconditions.checkNotNull(generator, "Generator not found for type: %s, service: %s", job.transferDataType(), job.importService());
String encodedJobId = ReferenceApiUtils.encodeJobId(jobId);
AuthFlowConfiguration authFlowConfiguration = generator.generateConfiguration(baseApiUrl, encodedJobId);
Preconditions.checkNotNull(authFlowConfiguration, "AuthFlowConfiguration not found for type: %s, service: %s", job.transferDataType(), job.importService());
// If present, store initial auth data for export services, e.g. used for oauth1
if (authFlowConfiguration.getInitialAuthData() != null) {
// Retrieve and parse the session key from the job
String sessionKey = job.jobAuthorization().sessionSecretKey();
SecretKey key = symmetricKeyGenerator.parse(BaseEncoding.base64Url().decode(sessionKey));
// Ensure intial auth data for import has not already been set
Preconditions.checkState(Strings.isNullOrEmpty(job.jobAuthorization().encryptedInitialImportAuthData()));
// Serialize and encrypt the initial auth data
String serialized = objectMapper.writeValueAsString(authFlowConfiguration.getInitialAuthData());
String encryptedInitialAuthData = EncrypterFactory.create(key).encrypt(serialized);
// Add the serialized and encrypted initial auth data to the job authorization
JobAuthorization updatedJobAuthorization = job.jobAuthorization().toBuilder().setEncryptedInitialImportAuthData(encryptedInitialAuthData).build();
// Persist the updated PortabilityJob with the updated JobAuthorization
PortabilityJob updatedPortabilityJob = job.toBuilder().setAndValidateJobAuthorization(updatedJobAuthorization).build();
store.updateJob(jobId, updatedPortabilityJob);
}
return new DataTransferResponse(job.exportService(), job.importService(), job.transferDataType(), Status.INPROCESS, // Redirect to auth page of import service
authFlowConfiguration.getUrl());
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class CreateJobAction method handle.
/**
* Given a set of job configuration parameters, this will create a new job and kick off auth flows
* for the specified configuration. TODO: Determine what to do if previous job exists in the
* session instead of creating a new job every time. TODO: Preconditions doesn't return an error
* code or page. So if a page is requested with invalid params or incorrect method, no error is
* present and the response is empty.
*/
@Override
public CreateJobActionResponse handle(CreateJobActionRequest request) {
String dataType = request.getTransferDataType();
Preconditions.checkArgument(!Strings.isNullOrEmpty(dataType), "Missing valid dataTypeParam: %s", dataType);
String exportService = request.getSource();
Preconditions.checkArgument(ActionUtils.isValidExportService(exportService), "Missing valid exportService: %s", exportService);
String importService = request.getDestination();
Preconditions.checkArgument(ActionUtils.isValidImportService(importService), "Missing valid importService: %s", importService);
// Create a new job and persist
UUID newId = UUID.randomUUID();
SecretKey sessionKey = symmetricKeyGenerator.generate();
String encodedSessionKey = BaseEncoding.base64Url().encode(sessionKey.getEncoded());
PortabilityJob job = createJob(encodedSessionKey, dataType, exportService, importService);
try {
store.createJob(newId, job);
} catch (IOException e) {
logger.warn("Error creating job with id: {}", newId, e);
return CreateJobActionResponse.createWithError("Unable to create a new job");
}
return CreateJobActionResponse.create(newId);
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class DataTransferHandler method handle.
/**
* Services the {@link CreateJobAction} via the {@link HttpExchange}.
*/
@Override
public void handle(HttpExchange exchange) throws IOException {
Preconditions.checkArgument(ReferenceApiUtils.validateRequest(exchange, HttpMethods.POST, PATH), PATH + " only supports POST.");
logger.debug("received request: {}", exchange.getRequestURI());
DataTransferRequest request = objectMapper.readValue(exchange.getRequestBody(), DataTransferRequest.class);
CreateJobActionRequest actionRequest = new CreateJobActionRequest(request.getSource(), request.getDestination(), request.getTransferDataType());
CreateJobActionResponse actionResponse = createJobAction.handle(actionRequest);
DataTransferResponse dataTransferResponse;
if (actionResponse.getErrorMsg() != null) {
logger.warn("Error during action: {}", actionResponse.getErrorMsg());
handleError(exchange, request);
return;
}
// Set new cookie
String encodedJobId = ReferenceApiUtils.encodeJobId(actionResponse.getId());
HttpCookie cookie = new HttpCookie(JsonKeys.ID_COOKIE_KEY, encodedJobId);
exchange.getResponseHeaders().add(HttpHeaders.SET_COOKIE, cookie.toString() + ReferenceApiUtils.COOKIE_ATTRIBUTES);
// Initial auth flow url
AuthDataGenerator generator = registry.getAuthDataGenerator(request.getSource(), request.getTransferDataType(), AuthMode.EXPORT);
Preconditions.checkNotNull(generator, "Generator not found for type: %s, service: %s", request.getTransferDataType(), request.getSource());
AuthFlowConfiguration authFlowConfiguration = generator.generateConfiguration(baseApiUrl, encodedJobId);
Preconditions.checkNotNull(authFlowConfiguration, "AuthFlowConfiguration not found for type: %s, service: %s", request.getTransferDataType(), request.getSource());
PortabilityJob job = store.findJob(actionResponse.getId());
logger.debug("Found job: {} in DTH", job);
// If present, store initial auth data for export services, e.g. used for oauth1
if (authFlowConfiguration.getInitialAuthData() != null) {
// Retrieve and parse the session key from the job
String sessionKey = job.jobAuthorization().sessionSecretKey();
SecretKey key = symmetricKeyGenerator.parse(BaseEncoding.base64Url().decode(sessionKey));
// Ensure intial auth data for export has not already been set
Preconditions.checkState(Strings.isNullOrEmpty(job.jobAuthorization().encryptedInitialExportAuthData()));
// Serialize and encrypt the initial auth data
String serialized = objectMapper.writeValueAsString(authFlowConfiguration.getInitialAuthData());
String encryptedInitialAuthData = EncrypterFactory.create(key).encrypt(serialized);
// Add the serialized and encrypted initial auth data to the job authorization
JobAuthorization updatedJobAuthorization = job.jobAuthorization().toBuilder().setEncryptedInitialExportAuthData(encryptedInitialAuthData).build();
// Persist the updated PortabilityJob with the updated JobAuthorization
PortabilityJob updatedPortabilityJob = job.toBuilder().setAndValidateJobAuthorization(updatedJobAuthorization).build();
store.updateJob(actionResponse.getId(), updatedPortabilityJob);
logger.debug("Updated job is: {}", updatedPortabilityJob);
PortabilityJob storejob = store.findJob(actionResponse.getId());
logger.debug("Job looked up in jobstore is: {} -> {}", actionResponse.getId(), storejob);
}
dataTransferResponse = new DataTransferResponse(request.getSource(), request.getDestination(), request.getTransferDataType(), Status.INPROCESS, authFlowConfiguration.getUrl());
logger.debug("redirecting to: {}", authFlowConfiguration.getUrl());
// Mark the response as type Json and send
exchange.getResponseHeaders().set(CONTENT_TYPE, "application/json; charset=" + StandardCharsets.UTF_8.name());
exchange.sendResponseHeaders(200, 0);
objectMapper.writeValue(exchange.getResponseBody(), dataTransferResponse);
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class StartJobAction method pollForPublicKey.
/**
* Polls until the a public key is assigned and persisted with the job. This key will subsquently
* be used to encrypt credentials.
*/
private PortabilityJob pollForPublicKey(UUID jobId) {
// Loop until the worker updates it to assigned without auth data state, e.g. at that point
// the worker instance key will be populated
// TODO: start new thread
// TODO: implement timeout condition
// TODO: Handle case where API dies while waiting
PortabilityJob job = store.findJob(jobId);
while (job == null || job.jobAuthorization().state() != JobAuthorization.State.CREDS_ENCRYPTION_KEY_GENERATED) {
logger.debug("Waiting for job {} to enter state CREDS_ENCRYPTION_KEY_GENERATED", jobId);
try {
Sleeper.DEFAULT.sleep(10000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
job = store.findJob(jobId);
}
logger.debug("Got job {} in state CREDS_ENCRYPTION_KEY_GENERATED", jobId);
// TODO: Consolidate validation with the internal PortabilityJob validation
Preconditions.checkNotNull(job.jobAuthorization().authPublicKey(), "Expected job " + jobId + " to have a worker instance's public key after being assigned " + "(state CREDS_ENCRYPTION_KEY_GENERATED)");
Preconditions.checkState(job.jobAuthorization().encryptedExportAuthData() == null, "Didn't expect job " + jobId + " to have encrypted export auth data yet in state " + "CREDS_ENCRYPTION_KEY_GENERATED");
Preconditions.checkState(job.jobAuthorization().encryptedImportAuthData() == null, "Didn't expect job " + jobId + " to have encrypted import auth data yet in state " + "CREDS_ENCRYPTION_KEY_GENERATED");
return job;
}
use of org.dataportabilityproject.spi.cloud.types.PortabilityJob in project data-transfer-project by google.
the class StartJobAction method updateStateToCredsAvailable.
/**
* Update the job to state to {@code State.CREDS_AVAILABLE} in the store. This indicates to the
* pool of workers that this job is available for processing.
*/
private void updateStateToCredsAvailable(UUID jobId) {
PortabilityJob job = store.findJob(jobId);
validateJob(job);
// Set update job auth data
JobAuthorization jobAuthorization = job.jobAuthorization().toBuilder().setState(State.CREDS_AVAILABLE).build();
job = job.toBuilder().setAndValidateJobAuthorization(jobAuthorization).build();
try {
store.updateJob(jobId, job);
logger.debug("Updated job {} to CREDS_AVAILABLE", jobId);
} catch (IOException e) {
throw new RuntimeException("Unable to update job", e);
}
}
Aggregations