package com.thinkbiganalytics.feedmgr.rest.controller;
/*-
* #%L
* thinkbig-feed-manager-controller
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.thinkbiganalytics.feedmgr.nifi.cache.NifiFlowCache;
import com.thinkbiganalytics.feedmgr.rest.model.EntityAccessRoleMembership;
import com.thinkbiganalytics.feedmgr.rest.model.NiFiTemplateFlowRequest;
import com.thinkbiganalytics.feedmgr.rest.model.NiFiTemplateFlowResponse;
import com.thinkbiganalytics.feedmgr.rest.model.RegisteredTemplate;
import com.thinkbiganalytics.feedmgr.rest.model.RegisteredTemplateRequest;
import com.thinkbiganalytics.feedmgr.rest.model.TemplateDtoWrapper;
import com.thinkbiganalytics.feedmgr.rest.model.TemplateOrder;
import com.thinkbiganalytics.feedmgr.rest.model.TemplateProcessorDatasourceDefinition;
import com.thinkbiganalytics.feedmgr.service.AccessControlledEntityTransform;
import com.thinkbiganalytics.feedmgr.service.MetadataService;
import com.thinkbiganalytics.feedmgr.service.datasource.DatasourceService;
import com.thinkbiganalytics.feedmgr.service.security.SecurityService;
import com.thinkbiganalytics.feedmgr.service.template.FeedManagerTemplateService;
import com.thinkbiganalytics.feedmgr.service.template.RegisteredTemplateService;
import com.thinkbiganalytics.metadata.rest.model.data.DatasourceDefinition;
import com.thinkbiganalytics.nifi.rest.client.LegacyNifiRestClient;
import com.thinkbiganalytics.nifi.rest.model.NifiProperty;
import com.thinkbiganalytics.nifi.rest.support.NifiConstants;
import com.thinkbiganalytics.rest.model.RestResponseStatus;
import com.thinkbiganalytics.security.rest.controller.SecurityModelTransform;
import com.thinkbiganalytics.security.rest.model.ActionGroup;
import com.thinkbiganalytics.security.rest.model.PermissionsChange;
import com.thinkbiganalytics.security.rest.model.RoleMembership;
import com.thinkbiganalytics.security.rest.model.RoleMembershipChange;
import com.thinkbiganalytics.security.rest.model.PermissionsChange.ChangeType;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.TemplateDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
@Api(tags = "Feed Manager - Templates", produces = "application/json")
@Path(TemplatesRestController.BASE)
@SwaggerDefinition(tags = @Tag(name = "Feed Manager - Templates", description = "manages templates"))
public class TemplatesRestController {
private static final Logger log = LoggerFactory.getLogger(TemplatesRestController.class);
public static final String BASE = "/v1/feedmgr/templates";
public static final String REGISTERED = "/registered";
@Autowired
LegacyNifiRestClient nifiRestClient;
@Autowired
MetadataService metadataService;
@Autowired
FeedManagerTemplateService feedManagerTemplateService;
@Autowired
DatasourceService datasourceService;
@Inject
private SecurityService securityService;
@Inject
private SecurityModelTransform actionsTransform;
@Inject
RegisteredTemplateService registeredTemplateService;
@Inject
NifiFlowCache nifiFlowCache;
@Inject
AccessControlledEntityTransform accessControlledEntityTransform;
private MetadataService getMetadataService() {
return metadataService;
}
/**
* This will list all the templates registered in Kylo
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of all templates.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the templates.", response = TemplateDtoWrapper.class, responseContainer = "Set"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getTemplates(@QueryParam("includeDetails") boolean includeDetails) {
Set<TemplateDTO> nifiTemplates = nifiRestClient.getTemplates(includeDetails);
Set<TemplateDtoWrapper> dtos = new HashSet<>();
List<RegisteredTemplate> registeredTemplates = registeredTemplateService.getRegisteredTemplates();
for (final TemplateDTO dto : nifiTemplates) {
RegisteredTemplate
match =
registeredTemplates.stream().filter(template -> template.getNifiTemplateId().equalsIgnoreCase(dto.getId()) || template.getTemplateName().equalsIgnoreCase(dto.getName())).findFirst()
.orElse(null);
TemplateDtoWrapper wrapper = new TemplateDtoWrapper(dto);
if (match != null) {
wrapper.setRegisteredTemplateId(match.getId());
}
dtos.add(wrapper);
}
return Response.ok(dtos).build();
}
/**
* This will populate the select drop down when a user asks to register a new template
*/
@GET
@Path("/unregistered")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of unregistered templates.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the templates.", response = TemplateDtoWrapper.class, responseContainer = "Set"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getUnregisteredTemplates(@QueryParam("includeDetails") boolean includeDetails) {
Set<TemplateDTO> nifiTemplates = nifiRestClient.getTemplates(includeDetails);
//List<RegisteredTemplate> registeredTemplates = metadataService.getRegisteredTemplates();
Set<TemplateDtoWrapper> dtos = new HashSet<>();
for (final TemplateDTO dto : nifiTemplates) {
RegisteredTemplate match = registeredTemplateService.findRegisteredTemplate(
RegisteredTemplateRequest.requestByNiFiTemplateProperties(dto.getId(), dto.getName()));
if (match == null) {
dtos.add(new TemplateDtoWrapper(dto));
}
}
return Response.ok(dtos).build();
}
@GET
@Path("/nifi/{templateId}/ports")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the ports in the specified template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the ports.", response = PortDTO.class, responseContainer = "Set"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getPortsForNifiTemplate(@PathParam("templateId") String nifiTemplateId) {
Set<PortDTO> ports = nifiRestClient.getPortsForTemplate(nifiTemplateId);
return Response.ok(ports).build();
}
@GET
@Path("/nifi/{templateId}/input-ports")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the input ports in the specified template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the input ports.", response = PortDTO.class, responseContainer = "Set"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getInputPortsForNifiTemplate(@PathParam("templateId") String nifiTemplateId) {
Set<PortDTO> ports = nifiRestClient.getPortsForTemplate(nifiTemplateId);
List<PortDTO> list = Lists.newArrayList(Iterables.filter(ports, new Predicate<PortDTO>() {
@Override
public boolean apply(PortDTO portDTO) {
return portDTO.getType().equalsIgnoreCase(NifiConstants.NIFI_PORT_TYPE.INPUT_PORT.name());
}
}));
return Response.ok(list).build();
}
@GET
@Path("/nifi/reusable-input-ports-processors")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the processors connected to the specified input ports.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the processors.", response = RegisteredTemplate.Processor.class, responseContainer = "List"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public List<RegisteredTemplate.Processor> getReusableTemplateProcessorsForInputPorts(@QueryParam("inputPorts") String inputPortIds) {
List<RegisteredTemplate.Processor> processorProperties = new ArrayList<>();
if (StringUtils.isNotBlank(inputPortIds)) {
List<String> inputPortIdsList = Arrays.asList(StringUtils.split(inputPortIds, ","));
processorProperties = feedManagerTemplateService.getReusableTemplateProcessorsForInputPorts(inputPortIdsList);
}
return processorProperties;
}
@GET
@Path("/nifi/{templateId}/processors")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the processors in the specified template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the processors.", response = RegisteredTemplate.Processor.class, responseContainer = "List"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getNiFiTemplateProcessors(@PathParam("templateId") String templateId) {
List<RegisteredTemplate.Processor> processorProperties = feedManagerTemplateService.getNiFiTemplateProcessorsWithProperties(templateId);
return Response.ok(processorProperties).build();
}
/**
* Returns data about the NiFiTemplate and its processors related to the input connections, along with the Datasources in the flow
*/
@POST
@Path("/nifi/{templateId}/flow-info")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the flow for the specified template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the flow.", response = NiFiTemplateFlowResponse.class),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getNiFiTemplateFlowInfo(@PathParam("templateId") String templateId, NiFiTemplateFlowRequest flowRequest) {
List<TemplateProcessorDatasourceDefinition> templateProcessorDatasourceDefinitions = new ArrayList<>();
NiFiTemplateFlowResponse response = new NiFiTemplateFlowResponse();
response.setRequest(flowRequest);
if (StringUtils.isNotBlank(templateId)) {
List<RegisteredTemplate.FlowProcessor> processors = feedManagerTemplateService.getNiFiTemplateFlowProcessors(templateId, flowRequest.getConnectionInfo());
Set<DatasourceDefinition> defs = datasourceService.getDatasourceDefinitions();
Map<String, DatasourceDefinition> datasourceDefinitionMap = new HashMap<>();
if (defs != null) {
defs.stream().forEach(def -> datasourceDefinitionMap.put(def.getProcessorType(), def));
}
templateProcessorDatasourceDefinitions = processors.stream().filter(processor -> datasourceDefinitionMap.containsKey(processor.getType())).map(p -> {
TemplateProcessorDatasourceDefinition definition = new TemplateProcessorDatasourceDefinition();
definition.setProcessorType(p.getType());
definition.setProcessorName(p.getName());
definition.setProcessorId(p.getId());
definition.setDatasourceDefinition(datasourceDefinitionMap.get(p.getType()));
return definition;
}).collect(Collectors.toList());
response.setProcessors(processors);
response.setTemplateProcessorDatasourceDefinitions(templateProcessorDatasourceDefinitions);
}
return Response.ok(response).build();
}
@GET
@Path("/reload-data-source-definitions")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Reloads the datasource definitions file.")
@ApiResponses(
@ApiResponse(code = 200, message = "The datasource definitions were reloaded.", response = RestResponseStatus.class)
)
public Response reloadDatasources() {
datasourceService.loadDefinitionsFromFile();
return Response.ok(RestResponseStatus.SUCCESS).build();
}
@GET
@Path("/nifi/{templateId}/out-ports")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the output ports for the specified template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the output ports.", response = PortDTO.class, responseContainer = "List"),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getOutputPortsForNifiTemplate(@PathParam("templateId") String nifiTemplateId) {
Set<PortDTO> ports = nifiRestClient.getPortsForTemplate(nifiTemplateId);
List<PortDTO> list = Lists.newArrayList(Iterables.filter(ports, new Predicate<PortDTO>() {
@Override
public boolean apply(PortDTO portDTO) {
return portDTO.getType().equalsIgnoreCase(NifiConstants.NIFI_PORT_TYPE.OUTPUT_PORT.name());
}
}));
return Response.ok(list).build();
}
/**
* get all the registered Templates
*
* @
*/
@GET
@Path(REGISTERED)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of registered templates.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the templates.", response = RegisteredTemplate.class, responseContainer = "List")
)
public Response getRegisteredTemplates() {
List<RegisteredTemplate> templates = getMetadataService().getRegisteredTemplates();
return Response.ok(templates).build();
}
/**
* Gets the template and optionally all reusable flow processors and properties
*/
@GET
@Path("/registered/{templateId}/processor-properties")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the processors of a registered template for input ports.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the processors.", response = RegisteredTemplate.Processor.class, responseContainer = "List")
)
public List<RegisteredTemplate.Processor> getReusableTemplateProcessorsForInputPorts(@PathParam("templateId") String templateId,
@QueryParam("includeReusableTemplates") boolean includeReusableTemplates) {
List<RegisteredTemplate.Processor> processorProperties = feedManagerTemplateService.getRegisteredTemplateProcessors(templateId, includeReusableTemplates);
return processorProperties;
}
/**
* get a given Registered Templates properties
*
* @
*/
@GET
@Path("/registered/{templateId}/properties")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the properties of a registered template.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the properties.", response = NifiProperty.class, responseContainer = "List")
)
public Response getRegisteredTemplateProperties(@PathParam("templateId") String templateId) {
return Response.ok(getMetadataService().getTemplateProperties(templateId)).build();
}
/**
* get a registeredTemplate for updating
*/
@GET
@Path("/registered/{templateId}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the specified registered template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the template.", response = RegisteredTemplate.class),
@ApiResponse(code = 500, message = "NiFi is unavailable.", response = RestResponseStatus.class)
})
public Response getRegisteredTemplate(@PathParam("templateId") String templateId, @QueryParam("allProperties") boolean allProperties, @QueryParam("feedName") String feedName,
@QueryParam("templateName") String templateName) {
RegisteredTemplateRequest
registeredTemplateRequest =
new RegisteredTemplateRequest.Builder().templateId(templateId).templateName(templateName).nifiTemplateId(templateId).includeAllProperties(allProperties).includePropertyDescriptors(true)
.isTemplateEdit(true).build();
RegisteredTemplate registeredTemplate = registeredTemplateService.getRegisteredTemplateForUpdate(registeredTemplateRequest);
return Response.ok(registeredTemplate).build();
}
@POST
@Path("/registered/{templateId}/enable")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Enables the specified registered template.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the template.", response = RegisteredTemplate.class)
)
public Response enableTemplate(@PathParam("templateId") String templateId) {
RegisteredTemplate enabledTemplate = feedManagerTemplateService.enableTemplate(templateId);
return Response.ok(enabledTemplate).build();
}
@POST
@Path("/registered/{templateId}/disable")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Disables the specified registered template.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the template.", response = RegisteredTemplate.class)
)
public Response disableTemplate(@PathParam("templateId") String templateId) {
RegisteredTemplate disabledTemplate = feedManagerTemplateService.disableTemplate(templateId);
return Response.ok(disabledTemplate).build();
}
@DELETE
@Path("/registered/{templateId}/delete")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Deletes the specified registered template.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the result.", response = RestResponseStatus.class)
)
public Response deleteTemplate(@PathParam("templateId") String templateId) {
boolean deleted = feedManagerTemplateService.deleteRegisteredTemplate(templateId);
return Response.ok(deleted ? new RestResponseStatus.ResponseStatusBuilder().buildSuccess() : new RestResponseStatus.ResponseStatusBuilder().buildError()).build();
}
@POST
@Path("/order")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Modifies the order of the registered templates.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the result.", response = RestResponseStatus.class)
)
public Response orderTemplates(TemplateOrder templateOrder) {
feedManagerTemplateService.orderTemplates(templateOrder.getTemplateIds(), null);
return Response.ok(new RestResponseStatus.ResponseStatusBuilder().buildSuccess()).build();
}
/**
* Register and save a given template and its properties
*
* @param registeredTemplate the template to register
*/
@POST
@Path("/register")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Registers the specified template.")
@ApiResponses(
@ApiResponse(code = 200, message = "The template was registered.", response = RegisteredTemplate.class)
)
public Response registerTemplate(RegisteredTemplate registeredTemplate) {
RegisteredTemplate saved = feedManagerTemplateService.registerTemplate(registeredTemplate);
return Response.ok(saved).build();
}
@GET
@Path("/registered/{templateId}/actions/available")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of available actions that may be permitted or revoked on a template.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the actions.", response = ActionGroup.class),
@ApiResponse(code = 404, message = "A template with the given ID does not exist.", response = RestResponseStatus.class)
})
public Response getAvailableActions(@PathParam("templateId") String templateIdStr) {
log.debug("Get available actions for template: {}", templateIdStr);
return this.securityService.getAvailableTemplateActions(templateIdStr)
.map(g -> Response.ok(g).build())
.orElseThrow(() -> new WebApplicationException("A template with the given ID does not exist: " + templateIdStr, Response.Status.NOT_FOUND));
}
@GET
@Path("/registered/{templateId}/actions/allowed")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of actions permitted for the given username and/or groups.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the actions.", response = ActionGroup.class),
@ApiResponse(code = 404, message = "A template with the given ID does not exist.", response = RestResponseStatus.class)
})
public Response getAllowedActions(@PathParam("templateId") String templateIdStr,
@QueryParam("user") Set<String> userNames,
@QueryParam("group") Set<String> groupNames) {
log.debug("Get allowed actions for template: {}", templateIdStr);
Set<? extends Principal> users = Arrays.stream(this.actionsTransform.asUserPrincipals(userNames)).collect(Collectors.toSet());
Set<? extends Principal> groups = Arrays.stream(this.actionsTransform.asGroupPrincipals(groupNames)).collect(Collectors.toSet());
return this.securityService.getAllowedTemplateActions(templateIdStr, Stream.concat(users.stream(), groups.stream()).collect(Collectors.toSet()))
.map(g -> Response.ok(g).build())
.orElseThrow(() -> new WebApplicationException("A template with the given ID does not exist: " + templateIdStr, Status.NOT_FOUND));
}
@POST
@Path("/registered/{templateId}/actions/allowed")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Updates the permissions for a template using the supplied permission change request.")
@ApiResponses({
@ApiResponse(code = 200, message = "The permissions were changed successfully.", response = ActionGroup.class),
@ApiResponse(code = 400, message = "The type is not valid.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "No template exists with the specified ID.", response = RestResponseStatus.class)
})
public Response postPermissionsChange(@PathParam("templateId") String templateIdStr,
PermissionsChange changes) {
return this.securityService.changeTemplatePermissions(templateIdStr, changes)
.map(g -> Response.ok(g).build())
.orElseThrow(() -> new WebApplicationException("A template with the given ID does not exist: " + templateIdStr, Response.Status.NOT_FOUND));
}
@GET
@Path("/registered/{templateId}/actions/change")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Constructs and returns a permission change request for a set of users/groups containing the actions that the requester may permit or revoke.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the change request that may be modified by the client and re-posted.", response = PermissionsChange.class),
@ApiResponse(code = 400, message = "The type is not valid.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "No template exists with the specified ID.", response = RestResponseStatus.class)
})
public Response getAllowedPermissionsChange(@PathParam("templateId") String templateIdStr,
@QueryParam("type") String changeType,
@QueryParam("user") Set<String> userNames,
@QueryParam("group") Set<String> groupNames) {
if (StringUtils.isBlank(changeType)) {
throw new WebApplicationException("The query parameter \"type\" is required", Status.BAD_REQUEST);
}
Set<? extends Principal> users = Arrays.stream(this.actionsTransform.asUserPrincipals(userNames)).collect(Collectors.toSet());
Set<? extends Principal> groups = Arrays.stream(this.actionsTransform.asGroupPrincipals(groupNames)).collect(Collectors.toSet());
return this.securityService.createTemplatePermissionChange(templateIdStr,
ChangeType.valueOf(changeType.toUpperCase()),
Stream.concat(users.stream(), groups.stream()).collect(Collectors.toSet()))
.map(p -> Response.ok(p).build())
.orElseThrow(() -> new WebApplicationException("A template with the given ID does not exist: " + templateIdStr, Status.NOT_FOUND));
}
@GET
@Path("/registered/{templateId}/roles")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of assigned members the template's roles")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the role memberships.", response = ActionGroup.class),
@ApiResponse(code = 404, message = "A template with the given ID does not exist.", response = RestResponseStatus.class)
})
public Response getRoleMemberships(@PathParam("templateId") String templateIdStr,@QueryParam("verbose") @DefaultValue("false") boolean verbose) {
if(!verbose) {
return this.securityService.getTemplateRoleMemberships(templateIdStr)
.map(m -> Response.ok(m).build())
.orElseThrow(() -> new WebApplicationException("A template with the given ID does not exist: " + templateIdStr, Status.NOT_FOUND));
}
else {
Optional<Map<String,RoleMembership>> memberships = this.securityService.getTemplateRoleMemberships(templateIdStr);
if(memberships.isPresent()){
List<EntityAccessRoleMembership> entityAccessRoleMemberships = memberships.get().values().stream().map(roleMembership -> accessControlledEntityTransform.toEntityAccessRoleMembership(roleMembership)).collect(Collectors.toList());
return Response.ok(entityAccessRoleMemberships).build();
}
else {
throw new WebApplicationException("A template with the given ID does not exist: " + templateIdStr, Status.NOT_FOUND);
}
}
}
@POST
@Path("/registered/{templateId}/roles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Updates the members of one of a template's roles.")
@ApiResponses({
@ApiResponse(code = 200, message = "The permissions were changed successfully.", response = ActionGroup.class),
@ApiResponse(code = 404, message = "No template exists with the specified ID.", response = RestResponseStatus.class)
})
public Response postPermissionsChange(@PathParam("templateId") String templateIdStr,
RoleMembershipChange changes) {
return this.securityService.changeTemplateRoleMemberships(templateIdStr, changes)
.map(m -> Response.ok(m).build())
.orElseThrow(() -> new WebApplicationException("Either a template with the ID \"" + templateIdStr
+ "\" does not exist or it does not have a role the named \""
+ changes.getRoleName() + "\"", Status.NOT_FOUND));
}
}