Search in sources :

Example 11 with PathsPromoteResult

use of org.commonjava.indy.promote.model.PathsPromoteResult in project indy by Commonjava.

the class PromoteResource method promotePaths.

@ApiOperation("Promote paths from a source repository into a target repository/group (subject to validation).")
@ApiResponse(code = 200, message = "Promotion operation finished (consult response content for success/failure).", response = PathsPromoteResult.class)
@ApiImplicitParam(name = "body", paramType = "body", value = "JSON request specifying source and target, with other configuration options", allowMultiple = false, required = true, dataType = "org.commonjava.indy.promote.model.PathsPromoteRequest")
@Path("/paths/promote")
@POST
@Consumes(ApplicationContent.application_json)
public Response promotePaths(@Context final HttpServletRequest request, @Context final UriInfo uriInfo) {
    PathsPromoteRequest req = null;
    Response response = null;
    try {
        final String json = IOUtils.toString(request.getInputStream());
        logger.info("Got promotion request:\n{}", json);
        req = mapper.readValue(json, PathsPromoteRequest.class);
    } catch (final IOException e) {
        response = formatResponse(e, "Failed to read DTO from request body.");
    }
    if (response != null) {
        return response;
    }
    try {
        PackageTypeDescriptor packageTypeDescriptor = PackageTypes.getPackageTypeDescriptor(req.getSource().getPackageType());
        final String baseUrl = uriInfo.getBaseUriBuilder().path(packageTypeDescriptor.getContentRestBasePath()).build(req.getSource().getType().singularEndpointName(), req.getSource().getName()).toString();
        final PathsPromoteResult result = manager.promotePaths(req, baseUrl);
        // TODO: Amend response status code based on presence of error? This would have consequences for client API...
        response = formatOkResponseWithJsonEntity(result, mapper);
    } catch (PromotionException | IndyWorkflowException e) {
        logger.error(e.getMessage(), e);
        response = formatResponse(e);
    }
    return response;
}
Also used : ResponseUtils.formatResponse(org.commonjava.indy.bind.jaxrs.util.ResponseUtils.formatResponse) Response(javax.ws.rs.core.Response) ApiResponse(io.swagger.annotations.ApiResponse) PathsPromoteResult(org.commonjava.indy.promote.model.PathsPromoteResult) PackageTypeDescriptor(org.commonjava.indy.model.core.PackageTypeDescriptor) IndyWorkflowException(org.commonjava.indy.IndyWorkflowException) PathsPromoteRequest(org.commonjava.indy.promote.model.PathsPromoteRequest) IOException(java.io.IOException) PromotionException(org.commonjava.indy.promote.data.PromotionException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) ApiOperation(io.swagger.annotations.ApiOperation) ApiImplicitParam(io.swagger.annotations.ApiImplicitParam) ApiResponse(io.swagger.annotations.ApiResponse)

Example 12 with PathsPromoteResult

use of org.commonjava.indy.promote.model.PathsPromoteResult in project indy by Commonjava.

the class PromoteResource method resumePaths.

@ApiOperation("RESUME promotion of paths from a source repository into a target repository/group (subject to validation), presumably after a previous failure condition has been corrected.")
@ApiResponse(code = 200, message = "Promotion operation finished (consult response content for success/failure).", response = PathsPromoteResult.class)
@ApiImplicitParam(name = "body", paramType = "body", value = "JSON result from previous attempt, specifying source and target, with other configuration options", allowMultiple = false, required = true, dataType = "org.commonjava.indy.promote.model.PathsPromoteResult")
@Path("/paths/resume")
@POST
@Consumes(ApplicationContent.application_json)
public Response resumePaths(@Context final HttpServletRequest request) {
    PathsPromoteResult result = null;
    Response response = null;
    try {
        result = mapper.readValue(request.getInputStream(), PathsPromoteResult.class);
    } catch (final IOException e) {
        response = formatResponse(e, "Failed to read DTO from request body.");
    }
    if (response != null) {
        return response;
    }
    try {
        result = manager.resumePathsPromote(result);
        // TODO: Amend response status code based on presence of error? This would have consequences for client API...
        response = formatOkResponseWithJsonEntity(result, mapper);
    } catch (PromotionException | IndyWorkflowException e) {
        logger.error(e.getMessage(), e);
        response = formatResponse(e);
    }
    return response;
}
Also used : ResponseUtils.formatResponse(org.commonjava.indy.bind.jaxrs.util.ResponseUtils.formatResponse) Response(javax.ws.rs.core.Response) ApiResponse(io.swagger.annotations.ApiResponse) PathsPromoteResult(org.commonjava.indy.promote.model.PathsPromoteResult) IndyWorkflowException(org.commonjava.indy.IndyWorkflowException) IOException(java.io.IOException) PromotionException(org.commonjava.indy.promote.data.PromotionException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) ApiOperation(io.swagger.annotations.ApiOperation) ApiImplicitParam(io.swagger.annotations.ApiImplicitParam) ApiResponse(io.swagger.annotations.ApiResponse)

Example 13 with PathsPromoteResult

use of org.commonjava.indy.promote.model.PathsPromoteResult in project indy by Commonjava.

the class PromoteResource method rollbackPaths.

@ApiOperation("Rollback promotion of any completed paths to a source repository from a target repository/group.")
@ApiResponse(code = 200, message = "Promotion operation finished (consult response content for success/failure).", response = PathsPromoteResult.class)
@ApiImplicitParam(name = "body", paramType = "body", value = "JSON result from previous attempt, specifying source and target, with other configuration options", allowMultiple = false, required = true, dataType = "org.commonjava.indy.promote.model.PathsPromoteResult")
@Path("/paths/rollback")
@POST
@Consumes(ApplicationContent.application_json)
public Response rollbackPaths(@Context final HttpServletRequest request, @Context final UriInfo uriInfo) {
    PathsPromoteResult result = null;
    Response response = null;
    try {
        result = mapper.readValue(request.getInputStream(), PathsPromoteResult.class);
    } catch (final IOException e) {
        response = formatResponse(e, "Failed to read DTO from request body.");
    }
    if (response != null) {
        return response;
    }
    try {
        result = manager.rollbackPathsPromote(result);
        // TODO: Amend response status code based on presence of error? This would have consequences for client API...
        response = formatOkResponseWithJsonEntity(result, mapper);
    } catch (PromotionException | IndyWorkflowException e) {
        logger.error(e.getMessage(), e);
        response = formatResponse(e);
    }
    return response;
}
Also used : ResponseUtils.formatResponse(org.commonjava.indy.bind.jaxrs.util.ResponseUtils.formatResponse) Response(javax.ws.rs.core.Response) ApiResponse(io.swagger.annotations.ApiResponse) PathsPromoteResult(org.commonjava.indy.promote.model.PathsPromoteResult) IndyWorkflowException(org.commonjava.indy.IndyWorkflowException) IOException(java.io.IOException) PromotionException(org.commonjava.indy.promote.data.PromotionException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) ApiOperation(io.swagger.annotations.ApiOperation) ApiImplicitParam(io.swagger.annotations.ApiImplicitParam) ApiResponse(io.swagger.annotations.ApiResponse)

Example 14 with PathsPromoteResult

use of org.commonjava.indy.promote.model.PathsPromoteResult in project indy by Commonjava.

the class RollbackTwoArtifactsTest method run.

@Test
public void run() throws Exception {
    PathsPromoteResult result = client.module(IndyPromoteClientModule.class).promoteByPath(new PathsPromoteRequest(source.getKey(), target.getKey()));
    assertThat(result.getRequest().getSource(), equalTo(source.getKey()));
    assertThat(result.getRequest().getTarget(), equalTo(target.getKey()));
    Set<String> pending = result.getPendingPaths();
    assertThat(pending == null || pending.isEmpty(), equalTo(true));
    Set<String> completed = result.getCompletedPaths();
    assertThat(completed, notNullValue());
    assertThat(completed.size(), equalTo(2));
    assertThat(result.getError(), nullValue());
    result = client.module(IndyPromoteClientModule.class).rollbackPathPromote(result);
    assertThat(result.getRequest().getSource(), equalTo(source.getKey()));
    assertThat(result.getRequest().getTarget(), equalTo(target.getKey()));
    completed = result.getCompletedPaths();
    assertThat(completed == null || completed.isEmpty(), equalTo(true));
    pending = result.getPendingPaths();
    assertThat(pending, notNullValue());
    assertThat(pending.size(), equalTo(2));
    assertThat(result.getError(), nullValue());
    assertThat(client.content().exists(target.getKey().getType(), target.getName(), first), equalTo(false));
    assertThat(client.content().exists(target.getKey().getType(), target.getName(), second), equalTo(false));
}
Also used : PathsPromoteResult(org.commonjava.indy.promote.model.PathsPromoteResult) PathsPromoteRequest(org.commonjava.indy.promote.model.PathsPromoteRequest) IndyPromoteClientModule(org.commonjava.indy.promote.client.IndyPromoteClientModule) Test(org.junit.Test)

Example 15 with PathsPromoteResult

use of org.commonjava.indy.promote.model.PathsPromoteResult in project indy by Commonjava.

the class PromotionManager method rollbackPathsPromote.

/**
     * Attempt to rollbackPathsPromote a previously failing {@link PathsPromoteResult}. This is meant to handle cases where an unrecoverable error
     * occurs on the server side, and promotion can NOT proceed afterward. All paths in the completed paths set are deleted from the target, if
     * possible. The output {@link PathsPromoteResult} contains the previous content, with any successfully removed target paths moved back from the
     * completed-paths list to the pending-paths list. If an error occurs during rollbackPathsPromote, the error field will be set...otherwise, it will be null.
     *
     * @param result The result to rollbackPathsPromote
     *
     * @return The same result, with any successful deletions moved from the completed to pending paths list, and the error cleared (or set to a
     * new error)
     *
     * @throws PromotionException
     * @throws IndyWorkflowException
     */
public PathsPromoteResult rollbackPathsPromote(final PathsPromoteResult result) throws PromotionException, IndyWorkflowException {
    StoreKey targetKey = result.getRequest().getTarget();
    ReentrantLock lock;
    synchronized (byPathTargetLocks) {
        lock = byPathTargetLocks.get(targetKey);
        if (lock == null) {
            lock = new ReentrantLock();
            byPathTargetLocks.put(targetKey, lock);
        }
    }
    final List<Transfer> contents = getTransfersForPaths(targetKey, result.getCompletedPaths());
    final Set<String> completed = result.getCompletedPaths();
    final Set<String> skipped = result.getSkippedPaths();
    if (completed == null || completed.isEmpty()) {
        result.setError(null);
        return result;
    }
    Set<String> pending = result.getPendingPaths();
    pending = pending == null ? new HashSet<String>() : new HashSet<String>(pending);
    String error = null;
    final boolean copyToSource = result.getRequest().isPurgeSource();
    ArtifactStore source = null;
    try {
        source = storeManager.getArtifactStore(result.getRequest().getSource());
    } catch (final IndyDataException e) {
        error = String.format("Failed to retrieve artifact store: %s. Reason: %s", result.getRequest().getSource(), e.getMessage());
        logger.error(error, e);
    }
    boolean locked = false;
    try {
        if (error == null) {
            locked = lock.tryLock(config.getLockTimeoutSeconds(), TimeUnit.SECONDS);
            if (!locked) {
                error = String.format("Failed to acquire promotion lock on target: %s in %d seconds.", targetKey, config.getLockTimeoutSeconds());
                logger.warn(error);
            }
        }
        if (error == null) {
            for (final Transfer transfer : contents) {
                if (transfer != null && transfer.exists()) {
                    InputStream stream = null;
                    try {
                        if (copyToSource) {
                            stream = transfer.openInputStream(true);
                            final String path = transfer.getPath();
                            contentManager.store(source, path, stream, TransferOperation.UPLOAD, new EventMetadata());
                            stream.close();
                        }
                        transfer.delete(true);
                        completed.remove(transfer.getPath());
                        pending.add(transfer.getPath());
                    } catch (final IOException e) {
                        error = String.format("Failed to rollback path promotion of: %s from: %s. Reason: %s", transfer, result.getRequest().getSource(), e.getMessage());
                        logger.error(error, e);
                    } finally {
                        closeQuietly(stream);
                    }
                }
            }
        }
    } catch (InterruptedException e) {
        error = String.format("Interrupted waiting for promotion lock on target: %s", targetKey);
        logger.warn(error);
    } finally {
        if (locked) {
            lock.unlock();
        }
    }
    return new PathsPromoteResult(result.getRequest(), pending, completed, skipped, error, new ValidationResult());
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) InputStream(java.io.InputStream) PathsPromoteResult(org.commonjava.indy.promote.model.PathsPromoteResult) IOException(java.io.IOException) ValidationResult(org.commonjava.indy.promote.model.ValidationResult) StoreKey(org.commonjava.indy.model.core.StoreKey) EventMetadata(org.commonjava.maven.galley.event.EventMetadata) IndyDataException(org.commonjava.indy.data.IndyDataException) ArtifactStore(org.commonjava.indy.model.core.ArtifactStore) Transfer(org.commonjava.maven.galley.model.Transfer) HashSet(java.util.HashSet)

Aggregations

PathsPromoteResult (org.commonjava.indy.promote.model.PathsPromoteResult)23 PathsPromoteRequest (org.commonjava.indy.promote.model.PathsPromoteRequest)18 Test (org.junit.Test)14 Transfer (org.commonjava.maven.galley.model.Transfer)10 EventMetadata (org.commonjava.maven.galley.event.EventMetadata)9 ByteArrayInputStream (java.io.ByteArrayInputStream)7 ChangeSummary (org.commonjava.indy.audit.ChangeSummary)7 HostedRepository (org.commonjava.indy.model.core.HostedRepository)7 IOException (java.io.IOException)6 InputStream (java.io.InputStream)5 IndyWorkflowException (org.commonjava.indy.IndyWorkflowException)5 StoreKey (org.commonjava.indy.model.core.StoreKey)5 IndyPromoteClientModule (org.commonjava.indy.promote.client.IndyPromoteClientModule)5 HashSet (java.util.HashSet)4 ValidationResult (org.commonjava.indy.promote.model.ValidationResult)4 ApiImplicitParam (io.swagger.annotations.ApiImplicitParam)3 ApiOperation (io.swagger.annotations.ApiOperation)3 ApiResponse (io.swagger.annotations.ApiResponse)3 Consumes (javax.ws.rs.Consumes)3 POST (javax.ws.rs.POST)3