Search in sources :

Example 1 with ServiceException

use of io.cdap.cdap.common.ServiceException in project cdap by caskdata.

the class AppLifecycleHttpHandler method upgradeApplications.

/**
 * Upgrades a lis of existing application to use latest version of application artifact and plugin artifacts.
 *
 * <pre>
 * {@code
 * [
 *   {"name":"XYZ"},
 *   {"name":"ABC"},
 *   {"name":"FOO"},
 * ]
 * }
 * </pre>
 * The response will be an array of {@link ApplicationUpdateDetail} object, which either indicates a success (200) or
 * failure for each of the requested application in the same order as the request. The failure also indicates reason
 * for the error. The response will be sent via ChunkResponder to continuously stream upgrade result per application.
 */
@POST
@Path("/upgrade")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void upgradeApplications(FullHttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @QueryParam("artifactScope") Set<String> artifactScopes, @QueryParam("allowSnapshot") boolean allowSnapshot) throws Exception {
    // TODO: (CDAP-16910) Improve batch API performance as each application upgrade is an event independent of each
    // other.
    List<ApplicationId> appIds = decodeAndValidateBatchApplicationRecord(validateNamespace(namespaceId), request);
    Set<ArtifactScope> allowedArtifactScopes = getArtifactScopes(artifactScopes);
    try (ChunkResponder chunkResponder = responder.sendChunkStart(HttpResponseStatus.OK)) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try (JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
            jsonWriter.beginArray();
            for (ApplicationId appId : appIds) {
                ApplicationUpdateDetail updateDetail;
                try {
                    applicationLifecycleService.upgradeApplication(appId, allowedArtifactScopes, allowSnapshot);
                    updateDetail = new ApplicationUpdateDetail(appId);
                } catch (UnsupportedOperationException e) {
                    String errorMessage = String.format("Application %s does not support upgrade.", appId);
                    updateDetail = new ApplicationUpdateDetail(appId, new NotImplementedException(errorMessage));
                } catch (InvalidArtifactException | NotFoundException e) {
                    updateDetail = new ApplicationUpdateDetail(appId, e);
                } catch (Exception e) {
                    updateDetail = new ApplicationUpdateDetail(appId, new ServiceException("Upgrade failed due to internal error.", e, HttpResponseStatus.INTERNAL_SERVER_ERROR));
                    LOG.error("Application upgrade failed with exception", e);
                }
                GSON.toJson(updateDetail, ApplicationUpdateDetail.class, jsonWriter);
                jsonWriter.flush();
                chunkResponder.sendChunk(Unpooled.wrappedBuffer(outputStream.toByteArray()));
                outputStream.reset();
                chunkResponder.flush();
            }
            jsonWriter.endArray();
        }
        chunkResponder.sendChunk(Unpooled.wrappedBuffer(outputStream.toByteArray()));
    }
}
Also used : NotImplementedException(io.cdap.cdap.common.NotImplementedException) ApplicationNotFoundException(io.cdap.cdap.common.ApplicationNotFoundException) NamespaceNotFoundException(io.cdap.cdap.common.NamespaceNotFoundException) NotFoundException(io.cdap.cdap.common.NotFoundException) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) JsonWriter(com.google.gson.stream.JsonWriter) ApplicationNotFoundException(io.cdap.cdap.common.ApplicationNotFoundException) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) NamespaceNotFoundException(io.cdap.cdap.common.NamespaceNotFoundException) WriteConflictException(io.cdap.cdap.internal.app.runtime.artifact.WriteConflictException) DatasetManagementException(io.cdap.cdap.api.dataset.DatasetManagementException) IOException(java.io.IOException) ConflictException(io.cdap.cdap.common.ConflictException) NotImplementedException(io.cdap.cdap.common.NotImplementedException) ExecutionException(java.util.concurrent.ExecutionException) AccessException(io.cdap.cdap.api.security.AccessException) InvalidArtifactException(io.cdap.cdap.common.InvalidArtifactException) ArtifactAlreadyExistsException(io.cdap.cdap.common.ArtifactAlreadyExistsException) NotFoundException(io.cdap.cdap.common.NotFoundException) ServiceException(io.cdap.cdap.common.ServiceException) JsonSyntaxException(com.google.gson.JsonSyntaxException) BadRequestException(io.cdap.cdap.common.BadRequestException) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) ArtifactScope(io.cdap.cdap.api.artifact.ArtifactScope) ApplicationUpdateDetail(io.cdap.cdap.proto.ApplicationUpdateDetail) ServiceException(io.cdap.cdap.common.ServiceException) OutputStreamWriter(java.io.OutputStreamWriter) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ChunkResponder(io.cdap.http.ChunkResponder) InvalidArtifactException(io.cdap.cdap.common.InvalidArtifactException) Path(javax.ws.rs.Path) AuditPolicy(io.cdap.cdap.common.security.AuditPolicy) POST(javax.ws.rs.POST)

Example 2 with ServiceException

use of io.cdap.cdap.common.ServiceException in project cdap by caskdata.

the class RuntimeServiceRoutingHandler method routeServiceWithBody.

/**
 * Handles PUT and POST calls from program runtime to access CDAP services.
 * It simply verify the request and forward the call to internal CDAP services.
 */
@Path("/services/{service}/**")
@PUT
@POST
public BodyConsumer routeServiceWithBody(HttpRequest request, HttpResponder responder, @PathParam("namespace") String namespace, @PathParam("app") String app, @PathParam("version") String version, @PathParam("program-type") String programType, @PathParam("program") String program, @PathParam("run") String run, @PathParam("service") String service) throws Exception {
    HttpURLConnection urlConn = openConnection(request, namespace, app, version, programType, program, run, service);
    urlConn.setDoOutput(true);
    OutputStream output;
    try {
        output = urlConn.getOutputStream();
    } catch (UnknownServiceException e) {
        throw new BadRequestException(e.getMessage(), e);
    } catch (IOException e) {
        // If fails to get output stream, treat it as service unavailable so that the client can retry
        throw new ServiceUnavailableException(service, e);
    }
    return new BodyConsumer() {

        @Override
        public void chunk(ByteBuf byteBuf, HttpResponder httpResponder) {
            try {
                byteBuf.readBytes(output, byteBuf.readableBytes());
            } catch (IOException e) {
                throw new ServiceUnavailableException(service, e);
            }
        }

        @Override
        public void finished(HttpResponder httpResponder) {
            try {
                output.close();
            } catch (IOException e) {
                throw new ServiceUnavailableException(service, e);
            }
            try {
                ResponseInfo responseInfo = new ResponseInfo(service, urlConn);
                responder.sendContent(HttpResponseStatus.valueOf(responseInfo.getResponseCode()), new RelayBodyProducer(urlConn.getURL(), responseInfo), responseInfo.getHeaders());
            } catch (BadRequestException e) {
                throw new ServiceException(e, HttpResponseStatus.BAD_REQUEST);
            }
        }

        @Override
        public void handleError(Throwable throwable) {
            LOG.warn("Exception raised for call to {}", urlConn.getURL(), throwable);
        }
    };
}
Also used : HttpResponder(io.cdap.http.HttpResponder) UnknownServiceException(java.net.UnknownServiceException) OutputStream(java.io.OutputStream) IOException(java.io.IOException) ServiceUnavailableException(io.cdap.cdap.common.ServiceUnavailableException) ByteBuf(io.netty.buffer.ByteBuf) HttpURLConnection(java.net.HttpURLConnection) UnknownServiceException(java.net.UnknownServiceException) ServiceException(io.cdap.cdap.common.ServiceException) BadRequestException(io.cdap.cdap.common.BadRequestException) BodyConsumer(io.cdap.http.BodyConsumer) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) PUT(javax.ws.rs.PUT)

Example 3 with ServiceException

use of io.cdap.cdap.common.ServiceException in project cdap by caskdata.

the class ImpersonationHandler method getCredentials.

@POST
@Path("/credentials")
public void getCredentials(FullHttpRequest request, HttpResponder responder) throws Exception {
    String requestContent = request.content().toString(StandardCharsets.UTF_8);
    if (requestContent == null) {
        throw new BadRequestException("Request body is empty.");
    }
    ImpersonationRequest impersonationRequest = GSON.fromJson(requestContent, ImpersonationRequest.class);
    LOG.debug("Fetching credentials for {}", impersonationRequest);
    UGIWithPrincipal ugiWithPrincipal;
    try {
        ugiWithPrincipal = ugiProvider.getConfiguredUGI(impersonationRequest);
    } catch (AccessException e) {
        throw new ServiceException(e, HttpResponseStatus.INTERNAL_SERVER_ERROR);
    }
    Credentials credentials = ImpersonationUtils.doAs(ugiWithPrincipal.getUGI(), new Callable<Credentials>() {

        @Override
        public Credentials call() throws Exception {
            return tokenSecureStoreRenewer.createCredentials();
        }
    });
    // example: hdfs:///cdap/credentials
    Location credentialsDir = locationFactory.create("credentials");
    if (credentialsDir.isDirectory() || credentialsDir.mkdirs() || credentialsDir.isDirectory()) {
        // the getTempFile() doesn't create the file within the directory that you call it on. It simply appends the path
        // without a separator, which is why we manually append the "tmp"
        // example: hdfs:///cdap/credentials/tmp.5960fe60-6fd8-4f3e-8e92-3fb6d4726006.credentials
        Location credentialsFile = credentialsDir.append("tmp").getTempFile(".credentials");
        // 600 is owner-only READ_WRITE
        try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(credentialsFile.getOutputStream("600")))) {
            credentials.writeTokenStorageToStream(os);
        }
        LOG.debug("Wrote credentials for user {} to {}", ugiWithPrincipal.getPrincipal(), credentialsFile);
        PrincipalCredentials principalCredentials = new PrincipalCredentials(ugiWithPrincipal.getPrincipal(), credentialsFile.toURI().toString());
        responder.sendJson(HttpResponseStatus.OK, GSON.toJson(principalCredentials));
    } else {
        throw new IllegalStateException("Unable to create credentials directory.");
    }
}
Also used : PrincipalCredentials(io.cdap.cdap.security.impersonation.PrincipalCredentials) UGIWithPrincipal(io.cdap.cdap.security.impersonation.UGIWithPrincipal) DataOutputStream(java.io.DataOutputStream) AccessException(io.cdap.cdap.api.security.AccessException) ServiceException(io.cdap.cdap.common.ServiceException) IOException(java.io.IOException) BadRequestException(io.cdap.cdap.common.BadRequestException) AccessException(io.cdap.cdap.api.security.AccessException) ServiceException(io.cdap.cdap.common.ServiceException) ImpersonationRequest(io.cdap.cdap.security.impersonation.ImpersonationRequest) BadRequestException(io.cdap.cdap.common.BadRequestException) BufferedOutputStream(java.io.BufferedOutputStream) Credentials(org.apache.hadoop.security.Credentials) PrincipalCredentials(io.cdap.cdap.security.impersonation.PrincipalCredentials) Location(org.apache.twill.filesystem.Location) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Aggregations

BadRequestException (io.cdap.cdap.common.BadRequestException)3 ServiceException (io.cdap.cdap.common.ServiceException)3 IOException (java.io.IOException)3 POST (javax.ws.rs.POST)3 Path (javax.ws.rs.Path)3 AccessException (io.cdap.cdap.api.security.AccessException)2 JsonSyntaxException (com.google.gson.JsonSyntaxException)1 JsonWriter (com.google.gson.stream.JsonWriter)1 ArtifactScope (io.cdap.cdap.api.artifact.ArtifactScope)1 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)1 ApplicationNotFoundException (io.cdap.cdap.common.ApplicationNotFoundException)1 ArtifactAlreadyExistsException (io.cdap.cdap.common.ArtifactAlreadyExistsException)1 ArtifactNotFoundException (io.cdap.cdap.common.ArtifactNotFoundException)1 ConflictException (io.cdap.cdap.common.ConflictException)1 InvalidArtifactException (io.cdap.cdap.common.InvalidArtifactException)1 NamespaceNotFoundException (io.cdap.cdap.common.NamespaceNotFoundException)1 NotFoundException (io.cdap.cdap.common.NotFoundException)1 NotImplementedException (io.cdap.cdap.common.NotImplementedException)1 ServiceUnavailableException (io.cdap.cdap.common.ServiceUnavailableException)1 AuditPolicy (io.cdap.cdap.common.security.AuditPolicy)1