Example usage for org.springframework.util.concurrent SettableListenableFuture addCallback

List of usage examples for org.springframework.util.concurrent SettableListenableFuture addCallback

Introduction

In this page you can find the example usage for org.springframework.util.concurrent SettableListenableFuture addCallback.

Prototype

@Override
    public void addCallback(ListenableFutureCallback<? super T> callback) 

Source Link

Usage

From source file:org.springframework.cloud.deployer.spi.yarn.YarnAppDeployer.java

@Override
public String deploy(AppDeploymentRequest request) {
    logger.info("Deploy request for {}", request);
    final AppDefinition definition = request.getDefinition();
    Map<String, String> definitionParameters = definition.getProperties();
    Map<String, String> deploymentProperties = request.getDeploymentProperties();
    logger.info("Deploying request for definition {}", definition);
    logger.info("Parameters for definition {}", definitionParameters);
    logger.info("Deployment properties for request {}", deploymentProperties);

    int count = 1;
    String countString = request.getDeploymentProperties().get(AppDeployer.COUNT_PROPERTY_KEY);
    if (StringUtils.hasText(countString)) {
        count = Integer.parseInt(countString);
    }//from  ww  w. j  a  v  a  2 s.  c o m
    final String group = request.getDeploymentProperties().get(AppDeployer.GROUP_PROPERTY_KEY);
    Resource resource = request.getResource();
    final String clusterId = group + ":" + definition.getName();

    // contextRunArgs are passed to boot app ran to control yarn apps
    ArrayList<String> contextRunArgs = new ArrayList<String>();
    contextRunArgs.add("--spring.yarn.appName=scdstream:app:" + group);

    // deployment properties override servers.yml which overrides application.yml
    for (Entry<String, String> entry : deploymentProperties.entrySet()) {
        if (entry.getKey().startsWith("spring.cloud.deployer.yarn.app.streamappmaster")) {
            contextRunArgs.add("--" + entry.getKey() + "=" + entry.getValue());
        } else if (entry.getKey().startsWith("spring.cloud.deployer.yarn.app.streamcontainer")) {
            // weird format with '--' is just straight pass to appmaster
            contextRunArgs.add("--spring.yarn.client.launchcontext.arguments.--" + entry.getKey() + "='"
                    + entry.getValue() + "'");
        }
    }

    String baseDir = yarnDeployerProperties.getBaseDir();
    if (!baseDir.endsWith("/")) {
        baseDir = baseDir + "/";
    }

    String artifactPath = isHdfsResource(resource) ? getHdfsArtifactPath(resource)
            : baseDir + "/artifacts/cache/";
    contextRunArgs
            .add("--spring.yarn.client.launchcontext.arguments.--spring.cloud.deployer.yarn.appmaster.artifact="
                    + artifactPath);

    // TODO: using default app name "app" until we start to customise
    //       via deploymentProperties
    final Message<String> message = MessageBuilder.withPayload(AppDeployerStateMachine.EVENT_DEPLOY)
            .setHeader(AppDeployerStateMachine.HEADER_APP_VERSION, "app")
            .setHeader(AppDeployerStateMachine.HEADER_CLUSTER_ID, clusterId)
            .setHeader(AppDeployerStateMachine.HEADER_GROUP_ID, group)
            .setHeader(AppDeployerStateMachine.HEADER_COUNT, count)
            .setHeader(AppDeployerStateMachine.HEADER_ARTIFACT, resource)
            .setHeader(AppDeployerStateMachine.HEADER_ARTIFACT_DIR, artifactPath)
            .setHeader(AppDeployerStateMachine.HEADER_DEFINITION_PARAMETERS, definitionParameters)
            .setHeader(AppDeployerStateMachine.HEADER_CONTEXT_RUN_ARGS, contextRunArgs).build();

    // Use of future here is to set id when it becomes available from machine
    final SettableListenableFuture<String> id = new SettableListenableFuture<>();
    final StateMachineListener<String, String> listener = new StateMachineListenerAdapter<String, String>() {

        @Override
        public void stateContext(StateContext<String, String> stateContext) {
            if (stateContext.getStage() == Stage.STATE_ENTRY
                    && stateContext.getTarget().getId().equals(AppDeployerStateMachine.STATE_READY)) {
                if (ObjectUtils.nullSafeEquals(message.getHeaders().getId().toString(), stateContext
                        .getExtendedState().get(AppDeployerStateMachine.VAR_MESSAGE_ID, String.class))) {
                    Exception exception = stateContext.getExtendedState().get(AppDeployerStateMachine.VAR_ERROR,
                            Exception.class);
                    if (exception != null) {
                        id.setException(exception);
                    } else {
                        String applicationId = stateContext.getStateMachine().getExtendedState()
                                .get(AppDeployerStateMachine.VAR_APPLICATION_ID, String.class);
                        DeploymentKey key = new DeploymentKey(group, definition.getName(), applicationId);
                        id.set(key.toString());
                    }
                }
            }
        }
    };
    stateMachine.addStateListener(listener);
    id.addCallback(new ListenableFutureCallback<String>() {

        @Override
        public void onSuccess(String result) {
            stateMachine.removeStateListener(listener);
        }

        @Override
        public void onFailure(Throwable ex) {
            stateMachine.removeStateListener(listener);
        }
    });

    stateMachine.sendEvent(message);
    // we need to block here until SPI supports
    // returning id asynchronously
    try {
        return id.get(2, TimeUnit.MINUTES);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

From source file:org.springframework.cloud.deployer.spi.yarn.YarnTaskLauncher.java

@Override
public String launch(AppDeploymentRequest request) {
    logger.info("Deploy request for {}", request);
    logger.info("Deploy request deployment properties {}", request.getDeploymentProperties());
    logger.info("Deploy definition {}", request.getDefinition());
    Resource resource = request.getResource();
    AppDefinition definition = request.getDefinition();

    String artifact = resource.getFilename();

    final String name = definition.getName();
    Map<String, String> definitionParameters = definition.getProperties();
    Map<String, String> deploymentProperties = request.getDeploymentProperties();
    List<String> commandlineArguments = request.getCommandlineArguments();
    String appName = "scdtask:" + name;

    // contextRunArgs are passed to boot app ran to control yarn apps
    // we pass needed args to control module coordinates and params,
    // weird format with '--' is just straight pass to container
    ArrayList<String> contextRunArgs = new ArrayList<String>();

    contextRunArgs.add("--spring.yarn.appName=" + appName);
    for (Entry<String, String> entry : definitionParameters.entrySet()) {
        if (StringUtils.hasText(entry.getValue())) {
            contextRunArgs.add(//from   w w  w . j  a va  2 s.  c  o m
                    "--spring.yarn.client.launchcontext.arguments.--spring.cloud.deployer.yarn.appmaster.parameters."
                            + entry.getKey() + ".='" + entry.getValue() + "'");
        }
    }

    int index = 0;
    for (String commandlineArgument : commandlineArguments) {
        contextRunArgs.add("--spring.yarn.client.launchcontext.argumentsList[" + index
                + "]='--spring.cloud.deployer.yarn.appmaster.commandlineArguments[" + index + "]="
                + commandlineArgument + "'");
        index++;
    }

    String baseDir = yarnDeployerProperties.getBaseDir();
    if (!baseDir.endsWith("/")) {
        baseDir = baseDir + "/";
    }
    String artifactPath = isHdfsResource(resource) ? getHdfsArtifactPath(resource)
            : baseDir + "/artifacts/cache/";

    contextRunArgs.add(
            "--spring.yarn.client.launchcontext.arguments.--spring.yarn.appmaster.launchcontext.archiveFile="
                    + artifact);
    contextRunArgs
            .add("--spring.yarn.client.launchcontext.arguments.--spring.cloud.deployer.yarn.appmaster.artifact="
                    + artifactPath + artifact);

    // deployment properties override servers.yml which overrides application.yml
    for (Entry<String, String> entry : deploymentProperties.entrySet()) {
        if (StringUtils.hasText(entry.getValue())) {
            if (entry.getKey().startsWith("spring.cloud.deployer.yarn.app.taskcontainer")) {
                contextRunArgs.add("--spring.yarn.client.launchcontext.arguments.--" + entry.getKey() + "='"
                        + entry.getValue() + "'");
            } else if (entry.getKey().startsWith("spring.cloud.deployer.yarn.app.taskappmaster")) {
                contextRunArgs.add("--" + entry.getKey() + "=" + entry.getValue());
            }
        }
    }

    final Message<String> message = MessageBuilder.withPayload(TaskLauncherStateMachine.EVENT_LAUNCH)
            .setHeader(TaskLauncherStateMachine.HEADER_APP_VERSION, "app")
            .setHeader(TaskLauncherStateMachine.HEADER_ARTIFACT, resource)
            .setHeader(TaskLauncherStateMachine.HEADER_ARTIFACT_DIR, artifactPath)
            .setHeader(TaskLauncherStateMachine.HEADER_DEFINITION_PARAMETERS, definitionParameters)
            .setHeader(TaskLauncherStateMachine.HEADER_CONTEXT_RUN_ARGS, contextRunArgs).build();

    // setup future, listen event from machine and finally unregister listener,
    // and set future value
    final SettableListenableFuture<String> id = new SettableListenableFuture<>();
    final StateMachineListener<String, String> listener = new StateMachineListenerAdapter<String, String>() {

        @Override
        public void stateContext(StateContext<String, String> stateContext) {
            if (stateContext.getStage() == Stage.STATE_ENTRY
                    && stateContext.getTarget().getId().equals(TaskLauncherStateMachine.STATE_READY)) {
                if (ObjectUtils.nullSafeEquals(message.getHeaders().getId().toString(), stateContext
                        .getExtendedState().get(TaskLauncherStateMachine.VAR_MESSAGE_ID, String.class))) {
                    Exception exception = stateContext.getExtendedState()
                            .get(TaskLauncherStateMachine.VAR_ERROR, Exception.class);
                    if (exception != null) {
                        id.setException(exception);
                    } else {
                        String applicationId = stateContext.getStateMachine().getExtendedState()
                                .get(TaskLauncherStateMachine.VAR_APPLICATION_ID, String.class);
                        DeploymentKey key = new DeploymentKey(name, applicationId);
                        id.set(key.toString());
                    }
                }
            }
        }
    };

    stateMachine.addStateListener(listener);
    id.addCallback(new ListenableFutureCallback<String>() {

        @Override
        public void onSuccess(String result) {
            stateMachine.removeStateListener(listener);
        }

        @Override
        public void onFailure(Throwable ex) {
            stateMachine.removeStateListener(listener);
        }
    });

    stateMachine.sendEvent(message);
    // we need to block here until SPI supports
    // returning id asynchronously
    try {
        return id.get(2, TimeUnit.MINUTES);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}