Search in sources :

Example 11 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class DeploymentGroupResource method rollingUpdate.

@POST
@Path("/{name}/rolling-update")
@Produces(APPLICATION_JSON)
@Timed
@ExceptionMetered
public Response rollingUpdate(@PathParam("name") @Valid final String name, @Valid final RollingUpdateRequest args) {
    try {
        final DeploymentGroup deploymentGroup = model.getDeploymentGroup(name);
        model.rollingUpdate(deploymentGroup, args.getJob(), args.getRolloutOptions());
        return Response.ok(new RollingUpdateResponse(RollingUpdateResponse.Status.OK)).build();
    } catch (DeploymentGroupDoesNotExistException e) {
        return Response.ok(new RollingUpdateResponse(RollingUpdateResponse.Status.DEPLOYMENT_GROUP_NOT_FOUND)).build();
    } catch (JobDoesNotExistException e) {
        return Response.ok(new RollingUpdateResponse(RollingUpdateResponse.Status.JOB_NOT_FOUND)).build();
    }
}
Also used : JobDoesNotExistException(com.spotify.helios.master.JobDoesNotExistException) RollingUpdateResponse(com.spotify.helios.common.protocol.RollingUpdateResponse) DeploymentGroupDoesNotExistException(com.spotify.helios.master.DeploymentGroupDoesNotExistException) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) Timed(com.codahale.metrics.annotation.Timed) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 12 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class DeploymentGroupResource method getDeploymentGroupStatus.

@GET
@Path("/{name}/status")
@Produces(APPLICATION_JSON)
@Timed
@ExceptionMetered
public Response getDeploymentGroupStatus(@PathParam("name") @Valid final String name) {
    try {
        final DeploymentGroup deploymentGroup = model.getDeploymentGroup(name);
        final DeploymentGroupStatus deploymentGroupStatus = model.getDeploymentGroupStatus(name);
        final List<String> hosts = model.getDeploymentGroupHosts(name);
        final List<DeploymentGroupStatusResponse.HostStatus> result = Lists.newArrayList();
        for (final String host : hosts) {
            final HostStatus hostStatus = model.getHostStatus(host);
            JobId deployedJobId = null;
            TaskStatus.State state = null;
            if (hostStatus != null && hostStatus.getStatus().equals(HostStatus.Status.UP)) {
                for (final Map.Entry<JobId, Deployment> entry : hostStatus.getJobs().entrySet()) {
                    if (name.equals(entry.getValue().getDeploymentGroupName())) {
                        deployedJobId = entry.getKey();
                        final TaskStatus taskStatus = hostStatus.getStatuses().get(deployedJobId);
                        if (taskStatus != null) {
                            state = taskStatus.getState();
                        }
                        break;
                    }
                }
                result.add(new DeploymentGroupStatusResponse.HostStatus(host, deployedJobId, state));
            }
        }
        final DeploymentGroupStatusResponse.Status status;
        if (deploymentGroupStatus == null) {
            status = DeploymentGroupStatusResponse.Status.IDLE;
        } else if (deploymentGroupStatus.getState() == DeploymentGroupStatus.State.FAILED) {
            status = DeploymentGroupStatusResponse.Status.FAILED;
        } else if (deploymentGroupStatus.getState() == DeploymentGroupStatus.State.ROLLING_OUT) {
            status = DeploymentGroupStatusResponse.Status.ROLLING_OUT;
        } else {
            status = DeploymentGroupStatusResponse.Status.ACTIVE;
        }
        final String error = deploymentGroupStatus == null ? "" : deploymentGroupStatus.getError();
        return Response.ok(new DeploymentGroupStatusResponse(deploymentGroup, status, error, result, deploymentGroupStatus)).build();
    } catch (final DeploymentGroupDoesNotExistException e) {
        return Response.status(Response.Status.NOT_FOUND).build();
    }
}
Also used : Deployment(com.spotify.helios.common.descriptors.Deployment) DeploymentGroupStatus(com.spotify.helios.common.descriptors.DeploymentGroupStatus) DeploymentGroupDoesNotExistException(com.spotify.helios.master.DeploymentGroupDoesNotExistException) TaskStatus(com.spotify.helios.common.descriptors.TaskStatus) DeploymentGroupStatusResponse(com.spotify.helios.common.protocol.DeploymentGroupStatusResponse) HostStatus(com.spotify.helios.common.descriptors.HostStatus) Map(java.util.Map) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) JobId(com.spotify.helios.common.descriptors.JobId) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) Timed(com.codahale.metrics.annotation.Timed) GET(javax.ws.rs.GET) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 13 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class ZooKeeperMasterModel method getDeploymentGroupStatus.

@Override
public DeploymentGroupStatus getDeploymentGroupStatus(final String name) throws DeploymentGroupDoesNotExistException {
    log.debug("getting deployment group status: {}", name);
    final ZooKeeperClient client = provider.get("getDeploymentGroupStatus");
    final DeploymentGroup deploymentGroup = getDeploymentGroup(client, name);
    if (deploymentGroup == null) {
        return null;
    }
    try {
        final Node node = client.getNode(Paths.statusDeploymentGroup(name));
        final byte[] bytes = node.getBytes();
        if (bytes.length == 0) {
            return null;
        }
        return Json.read(bytes, DeploymentGroupStatus.class);
    } catch (NoNodeException e) {
        return null;
    } catch (KeeperException | IOException e) {
        throw new HeliosRuntimeException("getting deployment group status " + name + " failed", e);
    }
}
Also used : NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) Node(com.spotify.helios.servicescommon.coordination.Node) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) IOException(java.io.IOException) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) KeeperException(org.apache.zookeeper.KeeperException)

Example 14 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class ZooKeeperMasterModel method getDeploymentGroups.

/**
   * Returns a {@link Map} of deployment group name to {@link DeploymentGroup} objects for all of
   * the deployment groups known.
   */
@Override
public Map<String, DeploymentGroup> getDeploymentGroups() {
    log.debug("getting deployment groups");
    final String folder = Paths.configDeploymentGroups();
    final ZooKeeperClient client = provider.get("getDeploymentGroups");
    try {
        final List<String> names;
        try {
            names = client.getChildren(folder);
        } catch (NoNodeException e) {
            return Maps.newHashMap();
        }
        final Map<String, DeploymentGroup> descriptors = Maps.newHashMap();
        for (final String name : names) {
            final String path = Paths.configDeploymentGroup(name);
            try {
                final byte[] data = client.getData(path);
                final DeploymentGroup descriptor = parse(data, DeploymentGroup.class);
                descriptors.put(descriptor.getName(), descriptor);
            } catch (NoNodeException e) {
                // Ignore, the deployment group was deleted before we had a chance to read it.
                log.debug("Ignoring deleted deployment group {}", name);
            }
        }
        return descriptors;
    } catch (KeeperException | IOException e) {
        throw new HeliosRuntimeException("getting deployment groups failed", e);
    }
}
Also used : NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) IOException(java.io.IOException) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) KeeperException(org.apache.zookeeper.KeeperException)

Example 15 with DeploymentGroup

use of com.spotify.helios.common.descriptors.DeploymentGroup in project helios by spotify.

the class ZooKeeperMasterModel method updateDeploymentGroupHosts.

@Override
public void updateDeploymentGroupHosts(final String groupName, final List<String> hosts) throws DeploymentGroupDoesNotExistException {
    log.debug("updating deployment-group hosts: name={}", groupName);
    final ZooKeeperClient client = provider.get("updateDeploymentGroupHosts");
    try {
        final DeploymentGroupStatus status = getDeploymentGroupStatus(groupName);
        if (!allowHostChange(status)) {
            return;
        }
        // statusDeploymentGroupRemovedHosts may not exist for deployment groups created before it was
        // introduced.
        client.ensurePathAndSetData(Paths.statusDeploymentGroupRemovedHosts(groupName), Json.asBytesUnchecked(emptyList()));
        final List<String> curHosts = getHosts(client, Paths.statusDeploymentGroupHosts(groupName));
        final List<String> previouslyRemovedHosts = getHosts(client, Paths.statusDeploymentGroupRemovedHosts(groupName));
        final List<String> removedHosts = removedHosts(curHosts, hosts, previouslyRemovedHosts);
        if (hosts.equals(curHosts) && removedHosts.equals(previouslyRemovedHosts)) {
            return;
        }
        log.info("for deployment-group name={}, curHosts={}, new hosts={}, " + "previouslyRemovedHosts={}, derived removedHosts={}", groupName, curHosts, hosts, previouslyRemovedHosts, removedHosts);
        final List<ZooKeeperOperation> ops = Lists.newArrayList();
        ops.add(set(Paths.statusDeploymentGroupHosts(groupName), Json.asBytes(hosts)));
        ops.add(set(Paths.statusDeploymentGroupRemovedHosts(groupName), Json.asBytes(removedHosts)));
        final Node dgn = client.getNode(Paths.configDeploymentGroup(groupName));
        final Integer deploymentGroupVersion = dgn.getStat().getVersion();
        DeploymentGroup deploymentGroup = Json.read(dgn.getBytes(), DeploymentGroup.class);
        List<Map<String, Object>> events = ImmutableList.of();
        if (deploymentGroup.getJobId() != null && updateOnHostChange(deploymentGroup, status)) {
            deploymentGroup = deploymentGroup.toBuilder().setRollingUpdateReason(HOSTS_CHANGED).build();
            // Fail transaction if the deployment group has been updated elsewhere.
            ops.add(check(Paths.configDeploymentGroup(groupName), deploymentGroupVersion));
            // NOTE: If the DG was removed this set() cause the transaction to fail, because
            // removing the DG removes this node. It's *important* that there's an operation that
            // causes the transaction to fail if the DG was removed or we'll end up with
            // inconsistent state.
            ops.add(set(Paths.configDeploymentGroup(deploymentGroup.getName()), deploymentGroup));
            final RollingUpdateOp op = getInitRollingUpdateOps(deploymentGroup, hosts, removedHosts, client);
            ops.addAll(op.operations());
            events = op.events();
        }
        log.info("starting zookeeper transaction for updateDeploymentGroupHosts on deployment-group: " + "name={} jobId={} operations={}", groupName, deploymentGroup.getJobId(), ops);
        client.transaction(ops);
        emitEvents(deploymentGroupEventTopic, events);
    } catch (BadVersionException e) {
        // some other master beat us in processing this host update. not exceptional.
        // ideally we would check the path in the exception, but curator doesn't provide a path
        // for exceptions thrown as part of a transaction.
        log.info("zookeeper transaction for updateDeploymentGroupHosts on deployment-group was " + "processed by another master: name={}", groupName);
    } catch (NoNodeException e) {
        throw new DeploymentGroupDoesNotExistException(groupName, e);
    } catch (KeeperException | IOException e) {
        throw new HeliosRuntimeException("updating deployment group hosts failed", e);
    }
}
Also used : NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) ZooKeeperOperation(com.spotify.helios.servicescommon.coordination.ZooKeeperOperation) Node(com.spotify.helios.servicescommon.coordination.Node) HeliosRuntimeException(com.spotify.helios.common.HeliosRuntimeException) DeploymentGroupStatus(com.spotify.helios.common.descriptors.DeploymentGroupStatus) BadVersionException(org.apache.zookeeper.KeeperException.BadVersionException) IOException(java.io.IOException) RollingUpdateOp(com.spotify.helios.rollingupdate.RollingUpdateOp) ZooKeeperClient(com.spotify.helios.servicescommon.coordination.ZooKeeperClient) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) Collections.emptyMap(java.util.Collections.emptyMap) DeploymentGroup(com.spotify.helios.common.descriptors.DeploymentGroup) KeeperException(org.apache.zookeeper.KeeperException)

Aggregations

DeploymentGroup (com.spotify.helios.common.descriptors.DeploymentGroup)30 Test (org.junit.Test)18 RolloutTask (com.spotify.helios.common.descriptors.RolloutTask)10 ZooKeeperClient (com.spotify.helios.servicescommon.coordination.ZooKeeperClient)10 HeliosRuntimeException (com.spotify.helios.common.HeliosRuntimeException)6 ZooKeeperOperation (com.spotify.helios.servicescommon.coordination.ZooKeeperOperation)6 Job (com.spotify.helios.common.descriptors.Job)4 CreateDeploymentGroupResponse (com.spotify.helios.common.protocol.CreateDeploymentGroupResponse)4 RollingUpdateResponse (com.spotify.helios.common.protocol.RollingUpdateResponse)4 KeeperException (org.apache.zookeeper.KeeperException)4 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)4 DeploymentGroupStatus (com.spotify.helios.common.descriptors.DeploymentGroupStatus)3 HostStatus (com.spotify.helios.common.descriptors.HostStatus)3 JobId (com.spotify.helios.common.descriptors.JobId)3 RemoveDeploymentGroupResponse (com.spotify.helios.common.protocol.RemoveDeploymentGroupResponse)3 DefaultZooKeeperClient (com.spotify.helios.servicescommon.coordination.DefaultZooKeeperClient)3 IOException (java.io.IOException)3 Response (javax.ws.rs.core.Response)3 ExceptionMetered (com.codahale.metrics.annotation.ExceptionMetered)2 Timed (com.codahale.metrics.annotation.Timed)2