package org.yamcs.web.rest; import java.util.List; import org.yamcs.YamcsServer; import org.yamcs.protobuf.Rest.EditServiceRequest; import org.yamcs.protobuf.Rest.ListServiceInfoResponse; import org.yamcs.protobuf.SchemaRest; import org.yamcs.protobuf.YamcsManagement.ServiceInfo; import org.yamcs.security.Privilege; import org.yamcs.web.BadRequestException; import org.yamcs.web.ForbiddenException; import org.yamcs.web.HttpException; import org.yamcs.web.InternalServerErrorException; import org.yamcs.web.NotFoundException; import com.google.common.util.concurrent.Service; /** * Gives information on services (instance specific or server wide) */ public class ServiceRestHandler extends RestHandler { static String GLOBAL_INSTANCE = "_global"; @Route(path="/api/services/:instance?", method="GET") public void listServices(RestRequest req) throws HttpException { checkPrivileges(req); String instance = req.getRouteParam("instance"); if(instance==null) throw new BadRequestException("No instance specified"); boolean global = false; if(GLOBAL_INSTANCE.equals(instance)) { global = true; } else { verifyInstance(req, instance); } List<ServiceInfo> slist; if(global) { slist = YamcsServer.getGlobalServices(); } else { YamcsServer ys = YamcsServer.getInstance(instance); slist = ys.getServices(); } ListServiceInfoResponse.Builder responseb = ListServiceInfoResponse.newBuilder(); responseb.addAllService(slist); completeOK(req, responseb.build(), SchemaRest.ListServiceInfoResponse.WRITE); } @Route(path="/api/services/:instance/:name", method={"PATCH", "PUT", "POST"}) @Route(path="/api/services/:instance/service/:name", method={"PATCH", "PUT", "POST"}) public void editService(RestRequest req) throws HttpException { checkPrivileges(req); String instance = req.getRouteParam("instance"); if(instance==null) throw new BadRequestException("No instance specified"); boolean global = false; if(GLOBAL_INSTANCE.equals(instance)) { global = true; } else { verifyInstance(req, instance); } String serviceName = req.getRouteParam("name"); EditServiceRequest request = req.bodyAsMessage(SchemaRest.EditServiceRequest.MERGE).build(); String state = null; if (request.hasState()) state = request.getState(); if (req.hasQueryParameter("state")) state = req.getQueryParameter("state"); if(serviceName==null) throw new BadRequestException("No service name specified"); if (state != null) { switch (state.toLowerCase()) { case "stop": case "stopped": Service s; if(global) { s = YamcsServer.getGlobalService(serviceName); } else { s = YamcsServer.getInstance(instance).getService(serviceName); } if(s==null) throw new NotFoundException(req, "No service by name '"+serviceName+"'"); s.stopAsync(); completeOK(req); return; case "running": try { if(global) { YamcsServer.startGlobalService(serviceName); } else { YamcsServer.getInstance(instance).startService(serviceName); } completeOK(req); } catch (Exception e) { completeWithError(req, new InternalServerErrorException(e)); } return; default: throw new BadRequestException("Unsupported service state '" + state + "'"); } } else { completeOK(req); } } private void checkPrivileges(RestRequest req) throws HttpException { if(!Privilege.getInstance().hasPrivilege1(req.getAuthToken(), Privilege.SystemPrivilege.MayControlServices)) { throw new ForbiddenException("No privilege for this operation"); } } }