Search in sources :

Example 56 with BadRequestException

use of co.cask.cdap.common.BadRequestException in project cdap by caskdata.

the class DefaultSecureStoreService method putSecureData.

/**
   * Puts the user provided data in the secure store, if the user has write access to the namespace. Grants the user
   * all access to the newly created entity.
   * @throws BadRequestException If the request does not contain the value to be stored.
   * @throws UnauthorizedException If the user does not have write permissions on the namespace.
   * @throws NamespaceNotFoundException If the specified namespace does not exist.
   * @throws AlreadyExistsException If the key already exists in the namespace. Updating is not supported.
   * @throws IOException If there was a problem storing the key to underlying provider.
   */
@Override
public final synchronized void putSecureData(String namespace, String name, String value, String description, Map<String, String> properties) throws Exception {
    Principal principal = authenticationContext.getPrincipal();
    NamespaceId namespaceId = new NamespaceId(namespace);
    authorizationEnforcer.enforce(namespaceId, principal, Action.WRITE);
    if (Strings.isNullOrEmpty(value)) {
        throw new BadRequestException("The data field should not be empty. This is the data that will be stored " + "securely.");
    }
    privilegesManager.grant(new SecureKeyId(namespace, name), principal, EnumSet.allOf(Action.class));
    secureStoreManager.putSecureData(namespace, name, value, description, properties);
}
Also used : Action(co.cask.cdap.proto.security.Action) SecureKeyId(co.cask.cdap.proto.id.SecureKeyId) BadRequestException(co.cask.cdap.common.BadRequestException) NamespaceId(co.cask.cdap.proto.id.NamespaceId) Principal(co.cask.cdap.proto.security.Principal)

Example 57 with BadRequestException

use of co.cask.cdap.common.BadRequestException in project cdap by caskdata.

the class ArtifactHttpHandler method callArtifactPluginMethod.

@Beta
@POST
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/" + "versions/{artifact-version}/plugintypes/{plugin-type}/plugins/{plugin-name}/methods/{plugin-method}")
@AuditPolicy({ AuditDetail.REQUEST_BODY, AuditDetail.RESPONSE_BODY })
public void callArtifactPluginMethod(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion, @PathParam("plugin-name") String pluginName, @PathParam("plugin-type") String pluginType, @PathParam("plugin-method") String methodName, @QueryParam("scope") @DefaultValue("user") String scope) throws Exception {
    String requestBody = request.getContent().toString(Charsets.UTF_8);
    NamespaceId namespace = Ids.namespace(namespaceId);
    NamespaceId artifactNamespace = validateAndGetScopedNamespace(namespace, scope);
    Id.Artifact artifactId = validateAndGetArtifactId(artifactNamespace, artifactName, artifactVersion);
    if (requestBody.isEmpty()) {
        throw new BadRequestException("Request body is used as plugin method parameter, " + "Received empty request body.");
    }
    try {
        PluginEndpoint pluginEndpoint = pluginService.getPluginEndpoint(namespace, artifactId, pluginType, pluginName, methodName);
        Object response = pluginEndpoint.invoke(GSON.fromJson(requestBody, pluginEndpoint.getMethodParameterType()));
        responder.sendString(HttpResponseStatus.OK, GSON.toJson(response));
    } catch (JsonSyntaxException e) {
        LOG.error("Exception while invoking plugin method.", e);
        responder.sendString(HttpResponseStatus.BAD_REQUEST, "Unable to deserialize request body to method parameter type");
    } catch (InvocationTargetException e) {
        LOG.error("Exception while invoking plugin method.", e);
        if (e.getCause() instanceof javax.ws.rs.NotFoundException) {
            throw new NotFoundException(e.getCause());
        } else if (e.getCause() instanceof javax.ws.rs.BadRequestException) {
            throw new BadRequestException(e.getCause());
        } else if (e.getCause() instanceof IllegalArgumentException && e.getCause() != null) {
            responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getCause().getMessage());
        } else {
            Throwable rootCause = Throwables.getRootCause(e);
            String message = String.format("Error while invoking plugin method %s.", methodName);
            if (rootCause != null && rootCause.getMessage() != null) {
                message = String.format("%s %s", message, rootCause.getMessage());
            }
            responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, message);
        }
    }
}
Also used : NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) ArtifactNotFoundException(co.cask.cdap.common.ArtifactNotFoundException) ArtifactRangeNotFoundException(co.cask.cdap.common.ArtifactRangeNotFoundException) NotFoundException(co.cask.cdap.common.NotFoundException) InvocationTargetException(java.lang.reflect.InvocationTargetException) JsonSyntaxException(com.google.gson.JsonSyntaxException) BadRequestException(co.cask.cdap.common.BadRequestException) PluginEndpoint(co.cask.cdap.internal.app.runtime.plugin.PluginEndpoint) NamespaceId(co.cask.cdap.proto.id.NamespaceId) Id(co.cask.cdap.proto.Id) ArtifactId(co.cask.cdap.proto.id.ArtifactId) NamespaceId(co.cask.cdap.proto.id.NamespaceId) Path(javax.ws.rs.Path) AuditPolicy(co.cask.cdap.common.security.AuditPolicy) POST(javax.ws.rs.POST) Beta(co.cask.cdap.api.annotation.Beta)

Example 58 with BadRequestException

use of co.cask.cdap.common.BadRequestException in project cdap by caskdata.

the class ArtifactHttpHandler method addArtifact.

@POST
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}")
@AuditPolicy(AuditDetail.HEADERS)
public BodyConsumer addArtifact(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") final String namespaceId, @PathParam("artifact-name") final String artifactName, @HeaderParam(VERSION_HEADER) final String artifactVersion, @HeaderParam(EXTENDS_HEADER) final String parentArtifactsStr, @HeaderParam(PLUGINS_HEADER) String pluginClasses) throws NamespaceNotFoundException, BadRequestException {
    final NamespaceId namespace = validateAndGetNamespace(namespaceId);
    // and validated there
    if (artifactVersion != null && !artifactVersion.isEmpty()) {
        validateAndGetArtifactId(namespace, artifactName, artifactVersion);
    }
    final Set<ArtifactRange> parentArtifacts = parseExtendsHeader(namespace, parentArtifactsStr);
    final Set<PluginClass> additionalPluginClasses;
    if (pluginClasses == null) {
        additionalPluginClasses = ImmutableSet.of();
    } else {
        try {
            additionalPluginClasses = GSON.fromJson(pluginClasses, PLUGINS_TYPE);
        } catch (JsonParseException e) {
            responder.sendString(HttpResponseStatus.BAD_REQUEST, String.format("%s header '%s' is invalid: %s", PLUGINS_HEADER, pluginClasses, e.getMessage()));
            return null;
        }
    }
    try {
        // copy the artifact contents to local tmp directory
        final File destination = File.createTempFile("artifact-", ".jar", tmpDir);
        return new AbstractBodyConsumer(destination) {

            @Override
            protected void onFinish(HttpResponder responder, File uploadedFile) {
                try {
                    String version = (artifactVersion == null || artifactVersion.isEmpty()) ? getBundleVersion(uploadedFile) : artifactVersion;
                    Id.Artifact artifactId = validateAndGetArtifactId(namespace, artifactName, version);
                    // add the artifact to the repo
                    artifactRepository.addArtifact(artifactId, uploadedFile, parentArtifacts, additionalPluginClasses);
                    responder.sendString(HttpResponseStatus.OK, "Artifact added successfully");
                } catch (ArtifactRangeNotFoundException e) {
                    responder.sendString(HttpResponseStatus.NOT_FOUND, e.getMessage());
                } catch (ArtifactAlreadyExistsException e) {
                    responder.sendString(HttpResponseStatus.CONFLICT, e.getMessage());
                } catch (WriteConflictException e) {
                    responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Conflict while writing artifact, please try again.");
                } catch (IOException e) {
                    LOG.error("Exception while trying to write artifact {}-{}-{}.", namespaceId, artifactName, artifactVersion, e);
                    responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error performing IO while writing artifact.");
                } catch (BadRequestException e) {
                    responder.sendString(HttpResponseStatus.BAD_REQUEST, e.getMessage());
                } catch (UnauthorizedException e) {
                    responder.sendString(HttpResponseStatus.FORBIDDEN, e.getMessage());
                } catch (Exception e) {
                    LOG.error("Error while writing artifact {}-{}-{}", namespaceId, artifactName, artifactVersion, e);
                    responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error while adding artifact.");
                }
            }

            private String getBundleVersion(File file) throws BadRequestException, IOException {
                try (JarFile jarFile = new JarFile(file)) {
                    Manifest manifest = jarFile.getManifest();
                    if (manifest == null) {
                        throw new BadRequestException("Unable to derive version from artifact because it does not contain a manifest. " + "Please package the jar with a manifest, or explicitly specify the artifact version.");
                    }
                    Attributes attributes = manifest.getMainAttributes();
                    String version = attributes == null ? null : attributes.getValue(ManifestFields.BUNDLE_VERSION);
                    if (version == null) {
                        throw new BadRequestException("Unable to derive version from artifact because manifest does not contain Bundle-Version attribute. " + "Please include Bundle-Version in the manifest, or explicitly specify the artifact version.");
                    }
                    return version;
                } catch (ZipException e) {
                    throw new BadRequestException("Artifact is not in zip format. Please make sure it is a jar file.");
                }
            }
        };
    } catch (IOException e) {
        LOG.error("Exception creating temp file to place artifact {} contents", artifactName, e);
        responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Server error creating temp file for artifact.");
        return null;
    }
}
Also used : ArtifactRangeNotFoundException(co.cask.cdap.common.ArtifactRangeNotFoundException) HttpResponder(co.cask.http.HttpResponder) ArtifactRange(co.cask.cdap.api.artifact.ArtifactRange) Attributes(java.util.jar.Attributes) ZipException(java.util.zip.ZipException) IOException(java.io.IOException) JsonParseException(com.google.gson.JsonParseException) JarFile(java.util.jar.JarFile) Manifest(java.util.jar.Manifest) InvalidArtifactRangeException(co.cask.cdap.api.artifact.InvalidArtifactRangeException) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) ArtifactNotFoundException(co.cask.cdap.common.ArtifactNotFoundException) ZipException(java.util.zip.ZipException) ArtifactAlreadyExistsException(co.cask.cdap.common.ArtifactAlreadyExistsException) InvocationTargetException(java.lang.reflect.InvocationTargetException) BadRequestException(co.cask.cdap.common.BadRequestException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) JsonParseException(com.google.gson.JsonParseException) PluginNotExistsException(co.cask.cdap.internal.app.runtime.plugin.PluginNotExistsException) ArtifactRangeNotFoundException(co.cask.cdap.common.ArtifactRangeNotFoundException) WriteConflictException(co.cask.cdap.internal.app.runtime.artifact.WriteConflictException) JsonSyntaxException(com.google.gson.JsonSyntaxException) IOException(java.io.IOException) NotFoundException(co.cask.cdap.common.NotFoundException) ArtifactAlreadyExistsException(co.cask.cdap.common.ArtifactAlreadyExistsException) AbstractBodyConsumer(co.cask.cdap.common.http.AbstractBodyConsumer) WriteConflictException(co.cask.cdap.internal.app.runtime.artifact.WriteConflictException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) BadRequestException(co.cask.cdap.common.BadRequestException) NamespaceId(co.cask.cdap.proto.id.NamespaceId) Id(co.cask.cdap.proto.Id) ArtifactId(co.cask.cdap.proto.id.ArtifactId) NamespaceId(co.cask.cdap.proto.id.NamespaceId) PluginClass(co.cask.cdap.api.plugin.PluginClass) JarFile(java.util.jar.JarFile) File(java.io.File) Path(javax.ws.rs.Path) AuditPolicy(co.cask.cdap.common.security.AuditPolicy) POST(javax.ws.rs.POST)

Example 59 with BadRequestException

use of co.cask.cdap.common.BadRequestException in project cdap by caskdata.

the class ImpersonationHandler method getCredentials.

@POST
@Path("/credentials")
public void getCredentials(HttpRequest request, HttpResponder responder) throws Exception {
    String requestContent = request.getContent().toString(Charsets.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 = ugiProvider.getConfiguredUGI(impersonationRequest);
    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, principalCredentials);
    } else {
        throw new IllegalStateException("Unable to create credentials directory.");
    }
}
Also used : PrincipalCredentials(co.cask.cdap.security.impersonation.PrincipalCredentials) UGIWithPrincipal(co.cask.cdap.security.impersonation.UGIWithPrincipal) DataOutputStream(java.io.DataOutputStream) BadRequestException(co.cask.cdap.common.BadRequestException) ImpersonationRequest(co.cask.cdap.security.impersonation.ImpersonationRequest) BadRequestException(co.cask.cdap.common.BadRequestException) BufferedOutputStream(java.io.BufferedOutputStream) Credentials(org.apache.hadoop.security.Credentials) PrincipalCredentials(co.cask.cdap.security.impersonation.PrincipalCredentials) Location(org.apache.twill.filesystem.Location) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 60 with BadRequestException

use of co.cask.cdap.common.BadRequestException in project cdap by caskdata.

the class MonitorHandler method setServiceInstance.

/**
   * Sets the number of instances of CDAP Services
   */
@Path("/system/services/{service-name}/instances")
@PUT
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void setServiceInstance(HttpRequest request, HttpResponder responder, @PathParam("service-name") final String serviceName) throws Exception {
    if (!serviceManagementMap.containsKey(serviceName)) {
        throw new NotFoundException(String.format("Invalid service name %s", serviceName));
    }
    MasterServiceManager serviceManager = serviceManagementMap.get(serviceName);
    int instances = getInstances(request);
    if (!serviceManager.isServiceEnabled()) {
        throw new ForbiddenException(String.format("Service %s is not enabled", serviceName));
    }
    int currentInstances = getSystemServiceInstanceCount(serviceName);
    if (instances < serviceManager.getMinInstances() || instances > serviceManager.getMaxInstances()) {
        String response = String.format("Instance count should be between [%s,%s]", serviceManager.getMinInstances(), serviceManager.getMaxInstances());
        throw new BadRequestException(response);
    } else if (instances == currentInstances) {
        responder.sendStatus(HttpResponseStatus.OK);
        return;
    }
    serviceStore.setServiceInstance(serviceName, instances);
    if (serviceManager.setInstances(instances)) {
        responder.sendStatus(HttpResponseStatus.OK);
    } else {
        throw new BadRequestException("Operation did not succeed");
    }
}
Also used : ForbiddenException(co.cask.cdap.common.ForbiddenException) MasterServiceManager(co.cask.cdap.common.twill.MasterServiceManager) NotFoundException(co.cask.cdap.common.NotFoundException) BadRequestException(co.cask.cdap.common.BadRequestException) Path(javax.ws.rs.Path) AuditPolicy(co.cask.cdap.common.security.AuditPolicy) PUT(javax.ws.rs.PUT)

Aggregations

BadRequestException (co.cask.cdap.common.BadRequestException)82 Path (javax.ws.rs.Path)29 NotFoundException (co.cask.cdap.common.NotFoundException)25 HttpResponse (co.cask.common.http.HttpResponse)17 JsonSyntaxException (com.google.gson.JsonSyntaxException)17 URL (java.net.URL)17 POST (javax.ws.rs.POST)17 NamespaceId (co.cask.cdap.proto.id.NamespaceId)16 IOException (java.io.IOException)15 ChannelBufferInputStream (org.jboss.netty.buffer.ChannelBufferInputStream)13 AuditPolicy (co.cask.cdap.common.security.AuditPolicy)12 HttpRequest (co.cask.common.http.HttpRequest)12 InputStreamReader (java.io.InputStreamReader)11 Reader (java.io.Reader)11 NamespaceNotFoundException (co.cask.cdap.common.NamespaceNotFoundException)9 ApplicationId (co.cask.cdap.proto.id.ApplicationId)8 ArtifactNotFoundException (co.cask.cdap.common.ArtifactNotFoundException)7 ProgramType (co.cask.cdap.proto.ProgramType)7 ProgramId (co.cask.cdap.proto.id.ProgramId)6 Test (org.junit.Test)6