package org.yamcs.web.rest.mdb; import java.util.HashSet; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yamcs.protobuf.Mdb.ParameterInfo; import org.yamcs.protobuf.Rest.BulkGetParameterInfoRequest; import org.yamcs.protobuf.Rest.BulkGetParameterInfoResponse; import org.yamcs.protobuf.Rest.ListParameterInfoResponse; import org.yamcs.protobuf.SchemaMdb; import org.yamcs.protobuf.SchemaRest; import org.yamcs.protobuf.Yamcs.NamedObjectId; import org.yamcs.security.Privilege; import org.yamcs.security.Privilege.Type; import org.yamcs.web.BadRequestException; import org.yamcs.web.HttpException; import org.yamcs.web.rest.RestHandler; import org.yamcs.web.rest.RestRequest; import org.yamcs.web.rest.Route; import org.yamcs.web.rest.mdb.XtceToGpbAssembler.DetailLevel; import org.yamcs.xtce.Parameter; import org.yamcs.xtce.SystemParameter; import org.yamcs.xtce.XtceDb; import org.yamcs.xtceproc.XtceDbFactory; /** * Handles incoming requests related to parameter info from the MDB */ public class MDBParameterRestHandler extends RestHandler { final static Logger log = LoggerFactory.getLogger(MDBParameterRestHandler.class); @Route(path = "/api/mdb/:instance/parameters/bulk", method = { "GET", "POST" }, priority = true) public void getBulkParameterInfo(RestRequest req) throws HttpException { String instance = verifyInstance(req, req.getRouteParam("instance")); XtceDb mdb = XtceDbFactory.getInstance(instance); BulkGetParameterInfoRequest request = req.bodyAsMessage(SchemaRest.BulkGetParameterInfoRequest.MERGE).build(); BulkGetParameterInfoResponse.Builder responseb = BulkGetParameterInfoResponse.newBuilder(); for(NamedObjectId id:request.getIdList()) { Parameter p = mdb.getParameter(id); if(p==null) { throw new BadRequestException("Invalid parameter name specified "+id); } if(!Privilege.getInstance().hasPrivilege1(req.getAuthToken(), Privilege.Type.TM_PARAMETER, p.getQualifiedName())) { log.warn("Not providing information about parameter {} because no privileges exists", p.getQualifiedName()); continue; } BulkGetParameterInfoResponse.GetParameterInfoResponse.Builder response = BulkGetParameterInfoResponse.GetParameterInfoResponse.newBuilder(); response.setId(id); String instanceURL = req.getApiURL() + "/mdb/" + instance; response.setParameter(XtceToGpbAssembler.toParameterInfo(p, instanceURL, DetailLevel.SUMMARY, req.getOptions())); responseb.addResponse(response); } completeOK(req, responseb.build(), SchemaRest.BulkGetParameterInfoResponse.WRITE); } @Route(path = "/api/mdb/:instance/parameters", method = "GET") @Route(path = "/api/mdb/:instance/parameters/:name*", method = "GET") public void getParameter(RestRequest req) throws HttpException { if (req.hasRouteParam("name")) { getParameterInfo(req); } else { listParameters(req); } } private void getParameterInfo(RestRequest req) throws HttpException { String instance = verifyInstance(req, req.getRouteParam("instance")); XtceDb mdb = XtceDbFactory.getInstance(instance); Parameter p = verifyParameter(req, mdb, req.getRouteParam("name")); String instanceURL = req.getApiURL() + "/mdb/" + instance; ParameterInfo pinfo = XtceToGpbAssembler.toParameterInfo(p, instanceURL, DetailLevel.FULL, req.getOptions()); completeOK(req, pinfo, SchemaMdb.ParameterInfo.WRITE); } private void listParameters(RestRequest req) throws HttpException { String instance = verifyInstance(req, req.getRouteParam("instance")); XtceDb mdb = XtceDbFactory.getInstance(instance); // Should eventually be replaced in a generic mdb search operation NameDescriptionSearchMatcher matcher = null; if (req.hasQueryParameter("q")) { matcher = new NameDescriptionSearchMatcher(req.getQueryParameter("q")); } String instanceURL = req.getApiURL() + "/mdb/" + instance; boolean recurse = req.getQueryParameterAsBoolean("recurse", false); boolean details = req.getQueryParameterAsBoolean("details", false); // Support both type[]=float&type[]=integer and type=float,integer Set<String> types = new HashSet<>(); if (req.hasQueryParameter("type")) { for (String type : req.getQueryParameterList("type")) { for (String t : type.split(",")) { if (!"all".equalsIgnoreCase(t)) { types.add(t.toLowerCase()); } } } } ListParameterInfoResponse.Builder responseb = ListParameterInfoResponse.newBuilder(); if (req.hasQueryParameter("namespace")) { String namespace = req.getQueryParameter("namespace"); Privilege privilege = Privilege.getInstance(); for (Parameter p : mdb.getParameters()) { if (!privilege.hasPrivilege1(req.getAuthToken(), Type.TM_PARAMETER, p.getQualifiedName())) continue; if (matcher != null && !matcher.matches(p)) continue; String alias = p.getAlias(namespace); if (alias != null || (recurse && p.getQualifiedName().startsWith(namespace))) { if (parameterTypeMatches(p, types)) { responseb.addParameter(XtceToGpbAssembler.toParameterInfo(p, instanceURL, details?DetailLevel.FULL:DetailLevel.SUMMARY, req.getOptions())); } } } } else { // List all for (Parameter p : mdb.getParameters()) { if (matcher != null && !matcher.matches(p)) continue; if (parameterTypeMatches(p, types)) { responseb.addParameter(XtceToGpbAssembler.toParameterInfo(p, instanceURL, details?DetailLevel.FULL:DetailLevel.SUMMARY, req.getOptions())); } } } completeOK(req, responseb.build(), SchemaRest.ListParameterInfoResponse.WRITE); } private boolean parameterTypeMatches(Parameter p, Set<String> types) { if (types.isEmpty()) return true; return p.getParameterType() != null && types.contains(p.getParameterType().getTypeAsString()); } }