brooklyn-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aledsage <...@git.apache.org>
Subject [GitHub] incubator-brooklyn pull request: Deploy across an entire web clust...
Date Tue, 29 Jul 2014 12:23:49 GMT
Github user aledsage commented on a diff in the pull request:

    https://github.com/apache/incubator-brooklyn/pull/83#discussion_r15519562
  
    --- Diff: software/webapp/src/main/java/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
---
    @@ -127,4 +158,140 @@ protected boolean calculateServiceUp() {
             }
             return up;
         }
    +    
    +    // TODO this will probably be useful elsewhere ... but where to put it?
    +    /** Waits for the given target to report service up, then runs the given task
    +     * (often an invocation on that entity), with the given name.
    +     * If the target goes away, this task marks itself inessential
    +     * before failing so as not to cause a parent task to fail. */
    +    static <T> Task<T> whenServiceUp(final Entity target, final TaskAdaptable<T>
task, String name) {
    +        return Tasks.<T>builder().name(name).dynamic(true).body(new Callable<T>()
{
    +            @Override
    +            public T call() {
    +                try {
    +                    while (true) {
    +                        if (!Entities.isManaged(target)) {
    +                            Tasks.markInessential();
    +                            throw new IllegalStateException("Target "+target+" is no
longer managed");
    +                        }
    +                        if (target.getAttribute(Attributes.SERVICE_UP)) {
    +                            Tasks.resetBlockingDetails();
    +                            TaskTags.markInessential(task);
    +                            DynamicTasks.queue(task);
    +                            try {
    +                                return task.asTask().getUnchecked();
    +                            } catch (Exception e) {
    +                                if (Entities.isManaged(target)) {
    +                                    throw Exceptions.propagate(e);
    +                                } else {
    +                                    Tasks.markInessential();
    +                                    throw new IllegalStateException("Target "+target+"
is no longer managed", e);
    +                                }
    +                            }
    +                        } else {
    +                            Tasks.setBlockingDetails("Waiting on "+target+" to be ready");
    +                        }
    +                        // TODO replace with subscription?
    +                        Time.sleep(Duration.ONE_SECOND);
    +                    }
    +                } finally {
    +                    Tasks.resetBlockingDetails();
    +                }
    +            }
    +        }).build();        
    +    }
    +
    +    @Override
    +    @Effector(description="Deploys the given artifact, from a source URL, to a given
deployment filename/context")
    +    public void deploy(
    +            @EffectorParam(name="url", description="URL of WAR file") String url, 
    +            @EffectorParam(name="targetName", description="context path where WAR should
be deployed (/ for ROOT)") String targetName) {
    +        checkNotNull(url, "url");
    +        checkNotNull(targetName, "targetName");
    +        targetName = filenameToWebContextMapper.convertDeploymentTargetNameToContext(targetName);
    +
    +        // set it up so future nodes get the right wars
    +        addToWarsByContext(this, url, targetName);
    +        
    +        log.debug("Deploying "+targetName+"->"+url+" across cluster "+this+"; WARs
now "+getConfig(WARS_BY_CONTEXT));
    +
    +        Iterable<CanDeployAndUndeploy> targets = Iterables.filter(getChildren(),
CanDeployAndUndeploy.class);
    +        TaskBuilder<Void> tb = Tasks.<Void>builder().parallel(true).name("Deploy
"+targetName+" to cluster (size "+Iterables.size(targets)+")");
    +        for (Entity target: targets) {
    +            tb.add(whenServiceUp(target, Effectors.invocation(target, DEPLOY, MutableMap.of("url",
url, "targetName", targetName)),
    +                "Deploy "+targetName+" to "+target+" when ready"));
    +        }
    +        DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked();
    +
    +        // Update attribute
    +        Set<String> deployedWars = MutableSet.copyOf(getAttribute(DEPLOYED_WARS));
    +        deployedWars.add(targetName);
    +        setAttribute(DEPLOYED_WARS, deployedWars);
    +    }
    +    
    +    @Override
    +    @Effector(description="Undeploys the given context/artifact")
    +    public void undeploy(@EffectorParam(name="targetName") String targetName) {
    +        checkNotNull(targetName, "targetName");
    +        targetName = filenameToWebContextMapper.convertDeploymentTargetNameToContext(targetName);
    +        
    +        // set it up so future nodes get the right wars
    +        removeFromWarsByContext(this, targetName);
    +        
    +        log.debug("Undeploying "+targetName+" across cluster "+this+"; WARs now "+getConfig(WARS_BY_CONTEXT));
    +
    +        Iterable<CanDeployAndUndeploy> targets = Iterables.filter(getChildren(),
CanDeployAndUndeploy.class);
    +        TaskBuilder<Void> tb = Tasks.<Void>builder().parallel(true).name("Undeploy
"+targetName+" across cluster (size "+Iterables.size(targets)+")");
    +        for (Entity target: targets) {
    +            tb.add(whenServiceUp(target, Effectors.invocation(target, UNDEPLOY, MutableMap.of("targetName",
targetName)),
    +                "Undeploy "+targetName+" at "+target+" when ready"));
    +        }
    +        DynamicTasks.queueIfPossible(tb.build()).orSubmitAsync(this).asTask().getUnchecked();
    +
    +        // Update attribute
    +        Set<String> deployedWars = MutableSet.copyOf(getAttribute(DEPLOYED_WARS));
    +        deployedWars.remove( filenameToWebContextMapper.convertDeploymentTargetNameToContext(targetName)
);
    +        setAttribute(DEPLOYED_WARS, deployedWars);
    +    }
    +
    +    static void addToWarsByContext(Entity entity, String url, String targetName) {
    +        targetName = filenameToWebContextMapper.convertDeploymentTargetNameToContext(targetName);
    +        synchronized (entity) {
    +            Map<String,String> newWarsMap = MutableMap.copyOf(entity.getConfig(WARS_BY_CONTEXT));
    +            newWarsMap.put(targetName, url);
    +            ((EntityInternal)entity).setConfig(WARS_BY_CONTEXT, newWarsMap);
    +        }
    +    }
    +
    +    static void removeFromWarsByContext(Entity entity, String targetName) {
    +        targetName = filenameToWebContextMapper.convertDeploymentTargetNameToContext(targetName);
    +        synchronized (entity) {
    +            Map<String,String> newWarsMap = MutableMap.copyOf(entity.getConfig(WARS_BY_CONTEXT));
    +            String url = newWarsMap.remove(targetName);
    +            if (url==null) {
    +                DynamicTasks.submit(Tasks.warning("Context "+targetName+" not known at
"+entity+"; attempting to undeploy regardless", null), entity);
    --- End diff --
    
    Instead of warning here, I'd prefer this method to return true/false to say whether it
was removed. If it wasn't then the caller can do the logging. The log message does not relate
to what this method is doing.
    
    The call in `ControlledDynamicWebAppClusterImpl` presumably doesn't need to do this logging
as we'll get exactly the same check when that calls `getCluster().undeploy(target)`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message