Search in sources :

Example 1 with FlowletConnection

use of co.cask.cdap.api.flow.FlowletConnection in project cdap by caskdata.

the class DefaultFlowConfigurer method connect.

@Override
public void connect(String from, String to) {
    Preconditions.checkArgument(from != null && to != null, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    Preconditions.checkArgument(flowlets.containsKey(from), UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NAME), from);
    Preconditions.checkArgument(flowlets.containsKey(to), UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NAME), to);
    connections.add(new FlowletConnection(FlowletConnection.Type.FLOWLET, from, to));
}
Also used : FlowletConnection(co.cask.cdap.api.flow.FlowletConnection)

Example 2 with FlowletConnection

use of co.cask.cdap.api.flow.FlowletConnection in project cdap by caskdata.

the class DefaultFlowConfigurer method connectStream.

@Override
public void connectStream(@Nullable String namespace, String stream, String flowlet) {
    Preconditions.checkNotNull(stream, UserMessages.getMessage(UserErrors.INVALID_STREAM_NULL));
    Preconditions.checkNotNull(flowlet, UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NULL));
    Preconditions.checkArgument(flowlets.containsKey(flowlet), UserMessages.getMessage(UserErrors.INVALID_FLOWLET_NAME), flowlet);
    connections.add(new FlowletConnection(FlowletConnection.Type.STREAM, namespace, stream, flowlet));
}
Also used : FlowletConnection(co.cask.cdap.api.flow.FlowletConnection)

Example 3 with FlowletConnection

use of co.cask.cdap.api.flow.FlowletConnection 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 4 with FlowletConnection

use of co.cask.cdap.api.flow.FlowletConnection in project cdap by caskdata.

the class FlowVerification method verify.

/**
   * Verifies a single {@link FlowSpecification} for a {@link co.cask.cdap.api.flow.Flow}.
   *
   * @param input to be verified
   * @return An instance of {@link VerifyResult} depending of status of verification.
   */
@Override
public VerifyResult verify(ApplicationId appId, final FlowSpecification input) {
    VerifyResult verifyResult = super.verify(appId, input);
    if (!verifyResult.isSuccess()) {
        return verifyResult;
    }
    String flowName = input.getName();
    // Check if there are no flowlets.
    if (input.getFlowlets().isEmpty()) {
        return VerifyResult.failure(Err.Flow.ATLEAST_ONE_FLOWLET, flowName);
    }
    // Check if there no connections.
    if (input.getConnections().isEmpty()) {
        return VerifyResult.failure(Err.Flow.ATLEAST_ONE_CONNECTION, flowName);
    }
    // We go through each Flowlet and verify the flowlets.
    // First collect all source flowlet names
    Set<String> sourceFlowletNames = Sets.newHashSet();
    for (FlowletConnection connection : input.getConnections()) {
        if (connection.getSourceType() == FlowletConnection.Type.FLOWLET) {
            sourceFlowletNames.add(connection.getSourceName());
        }
    }
    for (Map.Entry<String, FlowletDefinition> entry : input.getFlowlets().entrySet()) {
        FlowletDefinition defn = entry.getValue();
        String flowletName = defn.getFlowletSpec().getName();
        // Check if the Flowlet Name is an ID.
        if (!EntityId.isValidId(defn.getFlowletSpec().getName())) {
            return VerifyResult.failure(Err.NOT_AN_ID, flowName + ":" + flowletName);
        }
        // We check if all the dataset names used are ids
        for (String dataSet : defn.getDatasets()) {
            if (!EntityId.isValidDatasetId(dataSet)) {
                return VerifyResult.failure(Err.NOT_AN_ID, flowName + ":" + flowletName + ":" + dataSet);
            }
        }
        // Check if the flowlet has output, it must be appear as source flowlet in at least one connection
        if (entry.getValue().getOutputs().size() > 0 && !sourceFlowletNames.contains(flowletName)) {
            return VerifyResult.failure(Err.Flow.OUTPUT_NOT_CONNECTED, flowName, flowletName);
        }
    }
    // NOTE: We should unify the logic here and the queue spec generation, as they are doing the same thing.
    Table<QueueSpecificationGenerator.Node, String, Set<QueueSpecification>> queueSpecTable = new SimpleQueueSpecificationGenerator(appId).create(input);
    // For all connections, there should be an entry in the table.
    for (FlowletConnection connection : input.getConnections()) {
        QueueSpecificationGenerator.Node node;
        if (connection.getSourceType() == FlowletConnection.Type.FLOWLET) {
            node = new QueueSpecificationGenerator.Node(connection.getSourceType(), connection.getSourceName());
        } else {
            String sourceNamespace = connection.getSourceNamespace() == null ? appId.getNamespace() : connection.getSourceNamespace();
            node = new QueueSpecificationGenerator.Node(connection.getSourceType(), sourceNamespace, connection.getSourceName());
        }
        if (!queueSpecTable.contains(node, connection.getTargetName())) {
            return VerifyResult.failure(Err.Flow.NO_INPUT_FOR_OUTPUT, flowName, connection.getTargetName(), connection.getSourceType(), connection.getSourceName());
        }
    }
    // For each output entity, check for any unconnected output
    for (QueueSpecificationGenerator.Node node : queueSpecTable.rowKeySet()) {
        // For stream output, no need to check
        if (node.getType() == FlowletConnection.Type.STREAM) {
            continue;
        }
        // For all outputs of a flowlet, remove all the matched connected schema, if there is anything left,
        // then it's a incomplete flow connection (has output not connect to any input).
        Multimap<String, Schema> outputs = toMultimap(input.getFlowlets().get(node.getName()).getOutputs());
        for (Map.Entry<String, Set<QueueSpecification>> entry : queueSpecTable.row(node).entrySet()) {
            for (QueueSpecification queueSpec : entry.getValue()) {
                outputs.remove(queueSpec.getQueueName().getSimpleName(), queueSpec.getOutputSchema());
            }
        }
        if (!outputs.isEmpty()) {
            return VerifyResult.failure(Err.Flow.MORE_OUTPUT_NOT_ALLOWED, flowName, node.getType().toString().toLowerCase(), node.getName(), outputs);
        }
    }
    return VerifyResult.success();
}
Also used : Set(java.util.Set) FlowletConnection(co.cask.cdap.api.flow.FlowletConnection) Schema(co.cask.cdap.api.data.schema.Schema) SimpleQueueSpecificationGenerator(co.cask.cdap.internal.app.queue.SimpleQueueSpecificationGenerator) FlowletDefinition(co.cask.cdap.api.flow.FlowletDefinition) QueueSpecificationGenerator(co.cask.cdap.app.queue.QueueSpecificationGenerator) SimpleQueueSpecificationGenerator(co.cask.cdap.internal.app.queue.SimpleQueueSpecificationGenerator) QueueSpecification(co.cask.cdap.app.queue.QueueSpecification) VerifyResult(co.cask.cdap.app.verification.VerifyResult) Map(java.util.Map)

Example 5 with FlowletConnection

use of co.cask.cdap.api.flow.FlowletConnection in project cdap by caskdata.

the class FlowSpecificationCodec method deserialize.

@Override
public FlowSpecification deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    JsonObject jsonObj = json.getAsJsonObject();
    String className = jsonObj.get("className").getAsString();
    String name = jsonObj.get("name").getAsString();
    String description = jsonObj.get("description").getAsString();
    Map<String, FlowletDefinition> flowlets = deserializeMap(jsonObj.get("flowlets"), context, FlowletDefinition.class);
    List<FlowletConnection> connections = deserializeList(jsonObj.get("connections"), context, FlowletConnection.class);
    return new DefaultFlowSpecification(className, name, description, flowlets, connections);
}
Also used : FlowletDefinition(co.cask.cdap.api.flow.FlowletDefinition) FlowletConnection(co.cask.cdap.api.flow.FlowletConnection) JsonObject(com.google.gson.JsonObject) DefaultFlowSpecification(co.cask.cdap.internal.flow.DefaultFlowSpecification)

Aggregations

FlowletConnection (co.cask.cdap.api.flow.FlowletConnection)8 FlowletDefinition (co.cask.cdap.api.flow.FlowletDefinition)4 FlowSpecification (co.cask.cdap.api.flow.FlowSpecification)3 NamespaceId (co.cask.cdap.proto.id.NamespaceId)3 ProgramId (co.cask.cdap.proto.id.ProgramId)3 ApplicationSpecification (co.cask.cdap.api.app.ApplicationSpecification)2 QueueSpecification (co.cask.cdap.app.queue.QueueSpecification)2 ApplicationId (co.cask.cdap.proto.id.ApplicationId)2 Set (java.util.Set)2 ProgramSpecification (co.cask.cdap.api.ProgramSpecification)1 ArtifactId (co.cask.cdap.api.artifact.ArtifactId)1 Schema (co.cask.cdap.api.data.schema.Schema)1 MapReduceSpecification (co.cask.cdap.api.mapreduce.MapReduceSpecification)1 ServiceSpecification (co.cask.cdap.api.service.ServiceSpecification)1 HttpServiceHandlerSpecification (co.cask.cdap.api.service.http.HttpServiceHandlerSpecification)1 SparkSpecification (co.cask.cdap.api.spark.SparkSpecification)1 QueueSpecificationGenerator (co.cask.cdap.app.queue.QueueSpecificationGenerator)1 VerifyResult (co.cask.cdap.app.verification.VerifyResult)1 ApplicationNotFoundException (co.cask.cdap.common.ApplicationNotFoundException)1 ArtifactAlreadyExistsException (co.cask.cdap.common.ArtifactAlreadyExistsException)1