Search in sources :

Example 66 with ArtifactSummary

use of io.cdap.cdap.api.artifact.ArtifactSummary in project cdap by cdapio.

the class UpdateAppCommand method perform.

@Override
public void perform(Arguments arguments, PrintStream output) throws Exception {
    String appName = arguments.get(ArgumentName.APP.toString());
    ApplicationId appId = cliConfig.getCurrentNamespace().app(appName);
    String artifactName = arguments.get(ArgumentName.ARTIFACT_NAME.toString());
    String artifactVersion = arguments.get(ArgumentName.ARTIFACT_VERSION.toString());
    ArtifactScope artifactScope = ArtifactScope.valueOf(arguments.get(ArgumentName.SCOPE.toString()).toUpperCase());
    ArtifactSummary artifact = new ArtifactSummary(artifactName, artifactVersion, artifactScope);
    JsonObject config = new JsonObject();
    String configPath = arguments.getOptional(ArgumentName.APP_CONFIG_FILE.toString());
    if (configPath != null) {
        File configFile = resolver.resolvePathToFile(configPath);
        try (FileReader reader = new FileReader(configFile)) {
            AppRequest<JsonObject> appRequest = GSON.fromJson(reader, CONFIG_TYPE);
            config = appRequest.getConfig();
        }
    }
    AppRequest<JsonObject> appRequest = new AppRequest<>(artifact, config);
    applicationClient.update(appId, appRequest);
    output.println("Successfully updated application");
}
Also used : ArtifactScope(io.cdap.cdap.api.artifact.ArtifactScope) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) JsonObject(com.google.gson.JsonObject) FileReader(java.io.FileReader) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) File(java.io.File) AppRequest(io.cdap.cdap.proto.artifact.AppRequest)

Example 67 with ArtifactSummary

use of io.cdap.cdap.api.artifact.ArtifactSummary in project cdap by cdapio.

the class DefaultPreviewRunner method startPreview.

@Override
public Future<PreviewRequest> startPreview(PreviewRequest previewRequest) throws Exception {
    ProgramId programId = previewRequest.getProgram();
    long submitTimeMillis = RunIds.getTime(programId.getApplication(), TimeUnit.MILLISECONDS);
    previewStarted(programId);
    AppRequest<?> request = previewRequest.getAppRequest();
    if (request == null) {
        // This shouldn't happen
        throw new IllegalStateException("Preview request shouldn't have an empty application request");
    }
    ArtifactSummary artifactSummary = request.getArtifact();
    ApplicationId preview = programId.getParent();
    try {
        namespaceAdmin.create(new NamespaceMeta.Builder().setName(programId.getNamespaceId()).build());
    } catch (NamespaceAlreadyExistsException e) {
        LOG.debug("Namespace {} already exists.", programId.getNamespaceId());
    }
    DataTracerFactoryProvider.setDataTracerFactory(preview, dataTracerFactory);
    String config = request.getConfig() == null ? null : GSON.toJson(request.getConfig());
    PreviewConfig previewConfig = previewRequest.getAppRequest().getPreview();
    PreferencesDetail preferences = preferencesFetcher.get(programId, true);
    Map<String, String> userProps = new HashMap<>(preferences.getProperties());
    if (previewConfig != null) {
        userProps.putAll(previewConfig.getRuntimeArgs());
    }
    try {
        LOG.debug("Deploying preview application for {}", programId);
        applicationLifecycleService.deployApp(preview.getParent(), preview.getApplication(), preview.getVersion(), artifactSummary, config, NOOP_PROGRAM_TERMINATOR, null, request.canUpdateSchedules(), true, userProps);
    } catch (Exception e) {
        PreviewStatus previewStatus = new PreviewStatus(PreviewStatus.Status.DEPLOY_FAILED, submitTimeMillis, new BasicThrowable(e), null, null);
        previewTerminated(programId, previewStatus);
        throw e;
    }
    LOG.debug("Starting preview for {}", programId);
    ProgramController controller = programLifecycleService.start(programId, userProps, false, true);
    long startTimeMillis = System.currentTimeMillis();
    AtomicBoolean timeout = new AtomicBoolean();
    CompletableFuture<PreviewRequest> resultFuture = new CompletableFuture<>();
    controller.addListener(new AbstractListener() {

        @Override
        public void init(ProgramController.State currentState, @Nullable Throwable cause) {
            switch(currentState) {
                case STARTING:
                case ALIVE:
                case STOPPING:
                    setStatus(programId, new PreviewStatus(PreviewStatus.Status.RUNNING, submitTimeMillis, null, startTimeMillis, null));
                    break;
                case COMPLETED:
                    terminated(PreviewStatus.Status.COMPLETED, null);
                    break;
                case KILLED:
                    terminated(PreviewStatus.Status.KILLED, null);
                    break;
                case ERROR:
                    terminated(PreviewStatus.Status.RUN_FAILED, cause);
                    break;
            }
        }

        @Override
        public void completed() {
            terminated(PreviewStatus.Status.COMPLETED, null);
        }

        @Override
        public void killed() {
            terminated(timeout.get() ? PreviewStatus.Status.KILLED_BY_TIMER : PreviewStatus.Status.KILLED, null);
        }

        @Override
        public void error(Throwable cause) {
            terminated(PreviewStatus.Status.RUN_FAILED, cause);
        }

        /**
         * Handle termination of program run.
         *
         * @param status the termination status
         * @param failureCause if the program was terminated due to error, this carries the failure cause
         */
        private void terminated(PreviewStatus.Status status, @Nullable Throwable failureCause) {
            PreviewStatus previewStatus = new PreviewStatus(status, submitTimeMillis, failureCause == null ? null : new BasicThrowable(failureCause), startTimeMillis, System.currentTimeMillis());
            previewTerminated(programId, previewStatus);
            if (failureCause == null) {
                resultFuture.complete(previewRequest);
            } else {
                resultFuture.completeExceptionally(failureCause);
            }
        }
    }, Threads.SAME_THREAD_EXECUTOR);
    trackPreviewTimeout(previewRequest, timeout, resultFuture);
    PreviewMessage message = new PreviewMessage(PreviewMessage.Type.PROGRAM_RUN_ID, programId.getParent(), GSON.toJsonTree(controller.getProgramRunId()));
    previewDataPublisher.publish(programId.getParent(), message);
    return resultFuture;
}
Also used : HashMap(java.util.HashMap) PreferencesDetail(io.cdap.cdap.proto.PreferencesDetail) CompletableFuture(java.util.concurrent.CompletableFuture) NamespaceMeta(io.cdap.cdap.proto.NamespaceMeta) AbstractListener(io.cdap.cdap.internal.app.runtime.AbstractListener) NamespaceAlreadyExistsException(io.cdap.cdap.common.NamespaceAlreadyExistsException) ProgramController(io.cdap.cdap.app.runtime.ProgramController) PreviewMessage(io.cdap.cdap.app.preview.PreviewMessage) ProgramId(io.cdap.cdap.proto.id.ProgramId) TimeoutException(java.util.concurrent.TimeoutException) NamespaceAlreadyExistsException(io.cdap.cdap.common.NamespaceAlreadyExistsException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) PreviewStatus(io.cdap.cdap.app.preview.PreviewStatus) BasicThrowable(io.cdap.cdap.proto.BasicThrowable) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) BasicThrowable(io.cdap.cdap.proto.BasicThrowable) PreviewRequest(io.cdap.cdap.app.preview.PreviewRequest) PreviewConfig(io.cdap.cdap.proto.artifact.preview.PreviewConfig)

Example 68 with ArtifactSummary

use of io.cdap.cdap.api.artifact.ArtifactSummary in project cdap by cdapio.

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 if the current user has admin privileges on it before updating.
    accessEnforcer.enforce(appId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
    // check that app exists
    ApplicationSpecification currentSpec = store.getApplication(appId);
    if (currentSpec == null) {
        throw new ApplicationNotFoundException(appId);
    }
    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 = Id.Artifact.fromEntityId(Artifacts.toProtoArtifactId(appId.getParent(), newArtifactId));
    return deployApp(appId.getParent(), appId.getApplication(), null, artifactId, requestedConfigStr, programTerminator, ownerAdmin.getOwner(appId), appRequest.canUpdateSchedules());
}
Also used : ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) ArtifactVersion(io.cdap.cdap.api.artifact.ArtifactVersion) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) ApplicationNotFoundException(io.cdap.cdap.common.ApplicationNotFoundException) Gson(com.google.gson.Gson) Id(io.cdap.cdap.common.id.Id) InstanceId(io.cdap.cdap.proto.id.InstanceId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) EntityId(io.cdap.cdap.proto.id.EntityId) ProgramId(io.cdap.cdap.proto.id.ProgramId) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId) InvalidArtifactException(io.cdap.cdap.common.InvalidArtifactException)

Example 69 with ArtifactSummary

use of io.cdap.cdap.api.artifact.ArtifactSummary in project cdap by cdapio.

the class ApplicationLifecycleService method upgradeApplication.

/**
 * Upgrades an existing application by upgrading application artifact versions and plugin artifact versions.
 *
 * @param appId the id of the application to upgrade.
 * @param allowedArtifactScopes artifact scopes allowed while looking for latest artifacts for upgrade.
 * @param allowSnapshot whether to consider snapshot version of artifacts or not for upgrade.
 * @throws IllegalStateException if something unexpected happened during upgrade.
 * @throws IOException if there was an IO error during initializing application class from artifact.
 * @throws JsonIOException if there was an error in serializing or deserializing app config.
 * @throws UnsupportedOperationException if application does not support upgrade operation.
 * @throws InvalidArtifactException if candidate application artifact is invalid for upgrade purpose.
 * @throws NotFoundException if any object related to upgrade is not found like application/artifact.
 * @throws Exception if there was an exception during the upgrade of application. This exception will often wrap
 *                   the actual exception
 */
public void upgradeApplication(ApplicationId appId, Set<ArtifactScope> allowedArtifactScopes, boolean allowSnapshot) throws Exception {
    // Check if the current user has admin privileges on it before updating.
    accessEnforcer.enforce(appId, authenticationContext.getPrincipal(), StandardPermission.UPDATE);
    // check that app exists
    ApplicationSpecification currentSpec = store.getApplication(appId);
    if (currentSpec == null) {
        LOG.info("Application {} not found for upgrade.", appId);
        throw new NotFoundException(appId);
    }
    ArtifactId currentArtifact = currentSpec.getArtifactId();
    ArtifactSummary candidateArtifact = getLatestAppArtifactForUpgrade(appId, currentArtifact, allowedArtifactScopes, allowSnapshot);
    ArtifactVersion candidateArtifactVersion = new ArtifactVersion(candidateArtifact.getVersion());
    // Current artifact should not have higher version than candidate artifact.
    if (currentArtifact.getVersion().compareTo(candidateArtifactVersion) > 0) {
        String error = String.format("The current artifact has a version higher %s than any existing artifact.", currentArtifact.getVersion());
        throw new InvalidArtifactException(error);
    }
    ArtifactId newArtifactId = new ArtifactId(candidateArtifact.getName(), candidateArtifactVersion, candidateArtifact.getScope());
    Id.Artifact newArtifact = Id.Artifact.fromEntityId(Artifacts.toProtoArtifactId(appId.getParent(), newArtifactId));
    ArtifactDetail newArtifactDetail = artifactRepository.getArtifact(newArtifact);
    updateApplicationInternal(appId, currentSpec.getConfiguration(), programId -> {
    }, newArtifactDetail, Collections.singletonList(ApplicationConfigUpdateAction.UPGRADE_ARTIFACT), allowedArtifactScopes, allowSnapshot, ownerAdmin.getOwner(appId), false);
}
Also used : ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) ArtifactVersion(io.cdap.cdap.api.artifact.ArtifactVersion) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) ApplicationNotFoundException(io.cdap.cdap.common.ApplicationNotFoundException) NotFoundException(io.cdap.cdap.common.NotFoundException) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) Id(io.cdap.cdap.common.id.Id) InstanceId(io.cdap.cdap.proto.id.InstanceId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) EntityId(io.cdap.cdap.proto.id.EntityId) ProgramId(io.cdap.cdap.proto.id.ProgramId) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId) InvalidArtifactException(io.cdap.cdap.common.InvalidArtifactException) ArtifactDetail(io.cdap.cdap.internal.app.runtime.artifact.ArtifactDetail)

Example 70 with ArtifactSummary

use of io.cdap.cdap.api.artifact.ArtifactSummary in project cdap by cdapio.

the class SystemArtifactsAuthorizationTest method testAuthorizationForSystemArtifacts.

@Test
public void testAuthorizationForSystemArtifacts() throws Exception {
    artifactRepository.addSystemArtifacts();
    // alice should not be able to refresh system artifacts because she does not have admin privileges on namespace
    // system
    SecurityRequestContext.setUserId(ALICE.getName());
    try {
        artifactRepository.addSystemArtifacts();
        Assert.fail("Adding system artifacts should have failed because alice does not have admin privileges on " + "the namespace system.");
    } catch (UnauthorizedException expected) {
    // expected
    }
    // grant alice admin privileges on the CDAP system namespace
    Authorizable authorizable = Authorizable.fromEntityId(NamespaceId.SYSTEM, EntityType.ARTIFACT);
    accessController.grant(authorizable, ALICE, Collections.singleton(StandardPermission.CREATE));
    Assert.assertEquals(Collections.singleton(new GrantedPermission(authorizable, StandardPermission.CREATE)), accessController.listGrants(ALICE));
    // refreshing system artifacts should succeed now
    artifactRepository.addSystemArtifacts();
    SecurityRequestContext.setUserId("bob");
    // deleting a system artifact should fail because bob does not have admin privileges on the artifact
    try {
        artifactRepository.deleteArtifact(Id.Artifact.fromEntityId(SYSTEM_ARTIFACT));
        Assert.fail("Deleting a system artifact should have failed because alice does not have admin privileges on " + "the artifact.");
    } catch (UnauthorizedException expected) {
    // expected
    }
    // grant alice admin privileges on test namespace
    SecurityRequestContext.setUserId(ALICE.getName());
    NamespaceId namespaceId = new NamespaceId("test");
    accessController.grant(Authorizable.fromEntityId(namespaceId), ALICE, EnumSet.allOf(StandardPermission.class));
    accessController.grant(Authorizable.fromEntityId(namespaceId, EntityType.ARTIFACT), ALICE, EnumSet.of(StandardPermission.LIST));
    namespaceAdmin.create(new NamespaceMeta.Builder().setName(namespaceId.getNamespace()).build());
    // test that system artifacts are available to everyone
    List<ArtifactSummary> artifacts = artifactRepository.getArtifactSummaries(namespaceId, true);
    Assert.assertEquals(1, artifacts.size());
    ArtifactSummary artifactSummary = artifacts.get(0);
    Assert.assertEquals(SYSTEM_ARTIFACT.getArtifact(), artifactSummary.getName());
    Assert.assertEquals(SYSTEM_ARTIFACT.getVersion(), artifactSummary.getVersion());
    Assert.assertEquals(SYSTEM_ARTIFACT.getNamespace(), artifactSummary.getScope().name().toLowerCase());
    // test the getArtifact API
    ArtifactDetail artifactDetail = artifactRepository.getArtifact(Id.Artifact.fromEntityId(SYSTEM_ARTIFACT));
    io.cdap.cdap.api.artifact.ArtifactId artifactId = artifactDetail.getDescriptor().getArtifactId();
    Assert.assertEquals(SYSTEM_ARTIFACT.getArtifact(), artifactId.getName());
    Assert.assertEquals(SYSTEM_ARTIFACT.getVersion(), artifactId.getVersion().getVersion());
    Assert.assertEquals(SYSTEM_ARTIFACT.getNamespace(), artifactId.getScope().name().toLowerCase());
    namespaceAdmin.delete(namespaceId);
    // enforce on the system artifact should fail in unit test, since we do not have auto-grant now
    try {
        accessController.enforce(SYSTEM_ARTIFACT, ALICE, EnumSet.allOf(StandardPermission.class));
        Assert.fail();
    } catch (UnauthorizedException e) {
    // expected
    }
    try {
        artifactRepository.deleteArtifact(Id.Artifact.fromEntityId(SYSTEM_ARTIFACT));
        Assert.fail();
    } catch (UnauthorizedException e) {
    // expected
    }
    // deleting system artifact should succeed if alice has DELETE on the artifact
    accessController.grant(Authorizable.fromEntityId(SYSTEM_ARTIFACT), ALICE, EnumSet.of(StandardPermission.DELETE));
    artifactRepository.deleteArtifact(Id.Artifact.fromEntityId(SYSTEM_ARTIFACT));
    // clean up privilege
    accessController.revoke(Authorizable.fromEntityId(SYSTEM_ARTIFACT));
    accessController.revoke(Authorizable.fromEntityId(NamespaceId.SYSTEM, EntityType.ARTIFACT));
    accessController.revoke(Authorizable.fromEntityId(namespaceId, EntityType.ARTIFACT));
    accessController.revoke(Authorizable.fromEntityId(namespaceId));
}
Also used : GrantedPermission(io.cdap.cdap.proto.security.GrantedPermission) StandardPermission(io.cdap.cdap.proto.security.StandardPermission) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) NamespaceMeta(io.cdap.cdap.proto.NamespaceMeta) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) Authorizable(io.cdap.cdap.proto.security.Authorizable) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) Test(org.junit.Test)

Aggregations

ArtifactSummary (io.cdap.cdap.api.artifact.ArtifactSummary)152 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)86 AppRequest (io.cdap.cdap.proto.artifact.AppRequest)80 Test (org.junit.Test)70 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)48 ArtifactId (io.cdap.cdap.proto.id.ArtifactId)44 ProgramId (io.cdap.cdap.proto.id.ProgramId)44 Id (io.cdap.cdap.common.id.Id)36 ProfileId (io.cdap.cdap.proto.id.ProfileId)26 HttpResponse (io.cdap.common.http.HttpResponse)26 IOException (java.io.IOException)22 URL (java.net.URL)22 JsonObject (com.google.gson.JsonObject)18 NotFoundException (io.cdap.cdap.common.NotFoundException)18 ArtifactVersion (io.cdap.cdap.api.artifact.ArtifactVersion)16 ArtifactNotFoundException (io.cdap.cdap.common.ArtifactNotFoundException)16 File (java.io.File)16 Map (java.util.Map)16 ArtifactId (io.cdap.cdap.api.artifact.ArtifactId)14 KerberosPrincipalId (io.cdap.cdap.proto.id.KerberosPrincipalId)14