Search in sources :

Example 1 with Id

use of co.cask.cdap.proto.Id in project cdap by caskdata.

the class ApplicationLifecycleService method updateApp.

/**
   * Update an existing application. An application's configuration and artifact version can be updated.
   *
   * @param appId the id of the application to update
   * @param appRequest the request to update the application, including new config and artifact
   * @param programTerminator a program terminator that will stop programs that are removed when updating an app.
   *                          For example, if an update removes a flow, the terminator defines how to stop that flow.
   * @return information about the deployed application
   * @throws ApplicationNotFoundException if the specified application does not exist
   * @throws ArtifactNotFoundException if the requested artifact does not exist
   * @throws InvalidArtifactException if the specified artifact is invalid. For example, if the artifact name changed,
   *                                  if the version is an invalid version, or the artifact contains no app classes
   * @throws Exception if there was an exception during the deployment pipeline. This exception will often wrap
   *                   the actual exception
   */
public ApplicationWithPrograms updateApp(ApplicationId appId, AppRequest appRequest, ProgramTerminator programTerminator) throws Exception {
    // check that app exists
    ApplicationSpecification currentSpec = store.getApplication(appId);
    if (currentSpec == null) {
        throw new ApplicationNotFoundException(appId);
    }
    // App exists. Check if the current user has admin privileges on it before updating. The user's write privileges on
    // the namespace will get enforced in the deployApp method.
    authorizationEnforcer.enforce(appId, authenticationContext.getPrincipal(), Action.ADMIN);
    ArtifactId currentArtifact = currentSpec.getArtifactId();
    // if no artifact is given, use the current one.
    ArtifactId newArtifactId = currentArtifact;
    // otherwise, check requested artifact is valid and use it
    ArtifactSummary requestedArtifact = appRequest.getArtifact();
    if (requestedArtifact != null) {
        // cannot change artifact name, only artifact version.
        if (!currentArtifact.getName().equals(requestedArtifact.getName())) {
            throw new InvalidArtifactException(String.format(" Only artifact version updates are allowed. Cannot change from artifact '%s' to '%s'.", currentArtifact.getName(), requestedArtifact.getName()));
        }
        if (!currentArtifact.getScope().equals(requestedArtifact.getScope())) {
            throw new InvalidArtifactException("Only artifact version updates are allowed. " + "Cannot change from a non-system artifact to a system artifact or vice versa.");
        }
        // check requested artifact version is valid
        ArtifactVersion requestedVersion = new ArtifactVersion(requestedArtifact.getVersion());
        if (requestedVersion.getVersion() == null) {
            throw new InvalidArtifactException(String.format("Requested artifact version '%s' is invalid", requestedArtifact.getVersion()));
        }
        newArtifactId = new ArtifactId(currentArtifact.getName(), requestedVersion, currentArtifact.getScope());
    }
    // ownerAdmin.getImpersonationPrincipal will give the owner which will be impersonated for the application
    // irrespective of the version
    SecurityUtil.verifyOwnerPrincipal(appId, appRequest.getOwnerPrincipal(), ownerAdmin);
    Object requestedConfigObj = appRequest.getConfig();
    // if config is null, use the previous config. Shouldn't use a static GSON since the request Config object can
    // be a user class, otherwise there will be ClassLoader leakage.
    String requestedConfigStr = requestedConfigObj == null ? currentSpec.getConfiguration() : new Gson().toJson(requestedConfigObj);
    Id.Artifact artifactId = Artifacts.toArtifactId(appId.getParent(), newArtifactId).toId();
    return deployApp(appId.getParent(), appId.getApplication(), null, artifactId, requestedConfigStr, programTerminator, ownerAdmin.getOwner(appId), appRequest.canUpdateSchedules());
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) ArtifactSummary(co.cask.cdap.api.artifact.ArtifactSummary) ArtifactVersion(co.cask.cdap.api.artifact.ArtifactVersion) ArtifactId(co.cask.cdap.api.artifact.ArtifactId) ApplicationNotFoundException(co.cask.cdap.common.ApplicationNotFoundException) Gson(com.google.gson.Gson) ArtifactId(co.cask.cdap.api.artifact.ArtifactId) Id(co.cask.cdap.proto.Id) ProgramId(co.cask.cdap.proto.id.ProgramId) NamespaceId(co.cask.cdap.proto.id.NamespaceId) KerberosPrincipalId(co.cask.cdap.proto.id.KerberosPrincipalId) ApplicationId(co.cask.cdap.proto.id.ApplicationId) EntityId(co.cask.cdap.proto.id.EntityId) InvalidArtifactException(co.cask.cdap.common.InvalidArtifactException)

Example 2 with Id

use of co.cask.cdap.proto.Id in project cdap by caskdata.

the class ApplicationLifecycleService method deleteApp.

// deletes without performs checks that no programs are running
/**
   * Delete the specified application without performing checks that its programs are stopped.
   *
   * @param appId the id of the application to delete
   * @param spec the spec of the application to delete
   * @throws Exception
   */
private void deleteApp(final ApplicationId appId, ApplicationSpecification spec) throws Exception {
    Id.Application idApplication = appId.toId();
    // enforce ADMIN privileges on the app
    authorizationEnforcer.enforce(appId, authenticationContext.getPrincipal(), Action.ADMIN);
    // first remove all privileges on the app
    revokePrivileges(appId, spec);
    //Delete the schedules
    scheduler.deleteSchedules(appId);
    deleteMetrics(appId);
    //Delete all preferences of the application and of all its programs
    deletePreferences(appId);
    // TODO: This should be unified with the DeletedProgramHandlerStage
    for (final FlowSpecification flowSpecification : spec.getFlows().values()) {
        Id.Program flowProgramId = Id.Program.from(idApplication, ProgramType.FLOW, flowSpecification.getName());
        // Collects stream name to all group ids consuming that stream
        final Multimap<String, Long> streamGroups = HashMultimap.create();
        for (FlowletConnection connection : flowSpecification.getConnections()) {
            if (connection.getSourceType() == FlowletConnection.Type.STREAM) {
                long groupId = FlowUtils.generateConsumerGroupId(flowProgramId, connection.getTargetName());
                streamGroups.put(connection.getSourceName(), groupId);
            }
        }
        // Remove all process states and group states for each stream
        final String namespace = String.format("%s.%s", flowProgramId.getApplicationId(), flowProgramId.getId());
        impersonator.doAs(appId, new Callable<Void>() {

            // TODO: (CDAP-7326) since one worker or flow can only be ran by a single instance of APP, (also a single
            // version), should delete flow for each version
            @Override
            public Void call() throws Exception {
                for (Map.Entry<String, Collection<Long>> entry : streamGroups.asMap().entrySet()) {
                    streamConsumerFactory.dropAll(appId.getParent().stream(entry.getKey()), namespace, entry.getValue());
                }
                queueAdmin.dropAllForFlow(appId.flow(flowSpecification.getName()));
                return null;
            }
        });
    }
    ApplicationSpecification appSpec = store.getApplication(appId);
    deleteAppMetadata(appId, appSpec);
    deleteRouteConfig(appId, appSpec);
    store.deleteWorkflowStats(appId);
    store.removeApplication(appId);
    try {
        // delete the owner as it has already been determined that this is the only version of the app
        ownerAdmin.delete(appId);
    } catch (Exception e) {
        LOG.warn("Failed to delete app owner principal for application {} if one existed while deleting the " + "application.", appId);
    }
    try {
        usageRegistry.unregister(appId);
    } catch (Exception e) {
        LOG.warn("Failed to unregister usage of app: {}", appId, e);
    }
}
Also used : ApplicationSpecification(co.cask.cdap.api.app.ApplicationSpecification) FlowletConnection(co.cask.cdap.api.flow.FlowletConnection) CannotBeDeletedException(co.cask.cdap.common.CannotBeDeletedException) ApplicationNotFoundException(co.cask.cdap.common.ApplicationNotFoundException) ArtifactNotFoundException(co.cask.cdap.common.ArtifactNotFoundException) ArtifactAlreadyExistsException(co.cask.cdap.common.ArtifactAlreadyExistsException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) IOException(java.io.IOException) InvalidArtifactException(co.cask.cdap.common.InvalidArtifactException) ExecutionException(java.util.concurrent.ExecutionException) NotFoundException(co.cask.cdap.common.NotFoundException) FlowSpecification(co.cask.cdap.api.flow.FlowSpecification) ArtifactId(co.cask.cdap.api.artifact.ArtifactId) Id(co.cask.cdap.proto.Id) ProgramId(co.cask.cdap.proto.id.ProgramId) NamespaceId(co.cask.cdap.proto.id.NamespaceId) KerberosPrincipalId(co.cask.cdap.proto.id.KerberosPrincipalId) ApplicationId(co.cask.cdap.proto.id.ApplicationId) EntityId(co.cask.cdap.proto.id.EntityId)

Example 3 with Id

use of co.cask.cdap.proto.Id in project cdap by caskdata.

the class ArtifactHttpHandler method writeProperties.

@PUT
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/versions/{artifact-version}/properties")
@AuditPolicy(AuditDetail.REQUEST_BODY)
public void writeProperties(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion) throws Exception {
    NamespaceId namespace = NamespaceId.SYSTEM.getNamespace().equalsIgnoreCase(namespaceId) ? NamespaceId.SYSTEM : validateAndGetNamespace(namespaceId);
    Id.Artifact artifactId = validateAndGetArtifactId(namespace, artifactName, artifactVersion);
    Map<String, String> properties;
    try (Reader reader = new InputStreamReader(new ChannelBufferInputStream(request.getContent()), Charsets.UTF_8)) {
        properties = GSON.fromJson(reader, MAP_STRING_STRING_TYPE);
    } catch (JsonSyntaxException e) {
        throw new BadRequestException("Json Syntax Error while parsing properties from request. " + "Please check that the properties are a json map from string to string.", e);
    } catch (IOException e) {
        throw new BadRequestException("Unable to read properties from the request.", e);
    }
    try {
        artifactRepository.writeArtifactProperties(artifactId, properties);
        responder.sendStatus(HttpResponseStatus.OK);
    } catch (IOException e) {
        LOG.error("Exception writing properties for artifact {}.", artifactId, e);
        responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error adding properties to artifact.");
    }
}
Also used : JsonSyntaxException(com.google.gson.JsonSyntaxException) InputStreamReader(java.io.InputStreamReader) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) 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) ChannelBufferInputStream(org.jboss.netty.buffer.ChannelBufferInputStream) IOException(java.io.IOException) Path(javax.ws.rs.Path) AuditPolicy(co.cask.cdap.common.security.AuditPolicy) PUT(javax.ws.rs.PUT)

Example 4 with Id

use of co.cask.cdap.proto.Id in project cdap by caskdata.

the class ArtifactHttpHandler method getProperty.

@GET
@Path("/namespaces/{namespace-id}/artifacts/{artifact-name}/versions/{artifact-version}/properties/{property}")
public void getProperty(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("artifact-name") String artifactName, @PathParam("artifact-version") String artifactVersion, @PathParam("property") String key, @QueryParam("scope") @DefaultValue("user") String scope) throws Exception {
    NamespaceId namespace = validateAndGetScopedNamespace(Ids.namespace(namespaceId), scope);
    Id.Artifact artifactId = validateAndGetArtifactId(namespace, artifactName, artifactVersion);
    try {
        ArtifactDetail detail = artifactRepository.getArtifact(artifactId);
        responder.sendString(HttpResponseStatus.OK, detail.getMeta().getProperties().get(key));
    } catch (IOException e) {
        LOG.error("Exception reading property for artifact {}.", artifactId, e);
        responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Error reading properties for artifact.");
    }
}
Also used : 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) IOException(java.io.IOException) ArtifactDetail(co.cask.cdap.internal.app.runtime.artifact.ArtifactDetail) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 5 with Id

use of co.cask.cdap.proto.Id in project cdap by caskdata.

the class NamespacedIdCodec method deserializeProgramId.

private Id.Program deserializeProgramId(JsonObject id) {
    Id.Application app = deserializeApplicationId(id.getAsJsonObject("application"));
    ProgramType programType = ProgramType.valueOf(id.get("type").getAsString().toUpperCase());
    String programId = id.get("id").getAsString();
    return Id.Program.from(app, programType, programId);
}
Also used : Id(co.cask.cdap.proto.Id) ProgramType(co.cask.cdap.proto.ProgramType)

Aggregations

Id (co.cask.cdap.proto.Id)24 NamespaceId (co.cask.cdap.proto.id.NamespaceId)19 IOException (java.io.IOException)15 Path (javax.ws.rs.Path)14 ArtifactId (co.cask.cdap.proto.id.ArtifactId)13 GET (javax.ws.rs.GET)6 AuditPolicy (co.cask.cdap.common.security.AuditPolicy)5 ProgramId (co.cask.cdap.proto.id.ProgramId)5 ArtifactId (co.cask.cdap.api.artifact.ArtifactId)4 PluginClass (co.cask.cdap.api.plugin.PluginClass)4 ArtifactNotFoundException (co.cask.cdap.common.ArtifactNotFoundException)4 BadRequestException (co.cask.cdap.common.BadRequestException)4 ArtifactDescriptor (co.cask.cdap.internal.app.runtime.artifact.ArtifactDescriptor)4 ArtifactSummary (co.cask.cdap.api.artifact.ArtifactSummary)3 ArtifactVersion (co.cask.cdap.api.artifact.ArtifactVersion)3 ArtifactAlreadyExistsException (co.cask.cdap.common.ArtifactAlreadyExistsException)3 ArtifactRangeNotFoundException (co.cask.cdap.common.ArtifactRangeNotFoundException)3 NotFoundException (co.cask.cdap.common.NotFoundException)3 ArtifactDetail (co.cask.cdap.internal.app.runtime.artifact.ArtifactDetail)3 PluginNotExistsException (co.cask.cdap.internal.app.runtime.plugin.PluginNotExistsException)3