/* * Copyright 2013-2015 the original author or authors. * * 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. */ package org.springframework.xd.dirt.rest; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PagedResourcesAssembler; import org.springframework.hateoas.ExposesResourceFor; import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.mvc.ResourceAssemblerSupport; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.xd.dirt.module.ModuleNotDeployedException; import org.springframework.xd.dirt.module.store.ModuleMetadata; import org.springframework.xd.dirt.module.store.ModuleMetadataRepository; import org.springframework.xd.rest.domain.ModuleMetadataResource; /** * Controller that handles the interaction with the deployed modules. * * @author Ilayaperumal Gopinathan * @author Gunnar Hillert */ @Controller @RequestMapping("/runtime/modules") @ExposesResourceFor(ModuleMetadataResource.class) public class ModulesMetadataController { private final ModuleMetadataRepository moduleMetadataRepository; private ResourceAssemblerSupport<ModuleMetadata, ModuleMetadataResource> moduleMetadataResourceAssembler; @Autowired public ModulesMetadataController(ModuleMetadataRepository moduleMetadataRepository) { this.moduleMetadataRepository = moduleMetadataRepository; moduleMetadataResourceAssembler = new ModuleMetadataResourceAssembler(); } /** * List module metadata for all the deployed modules. * * @param pageable pagination information * @param assembler paged resource assembler * @return paged {@link ModuleMetadataResource} */ @RequestMapping(value = "", method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) @ResponseBody public PagedResources<ModuleMetadataResource> list(Pageable pageable, PagedResourcesAssembler<ModuleMetadata> assembler) { final Page<ModuleMetadata> page = this.moduleMetadataRepository.findAll(pageable); return maskSensitiveData(assembler.toResource(page, moduleMetadataResourceAssembler)); } /** * List the module metadata for all the modules that are deployed to the given container. * * @param pageable pagination information * @param assembler paged resource assembler * @param containerId the container id of the container to choose * @return paged {@link ModuleMetadataResource} */ @RequestMapping(value = "", method = RequestMethod.GET, params = { "containerId" }) @ResponseStatus(HttpStatus.OK) @ResponseBody public PagedResources<ModuleMetadataResource> listByContainer(Pageable pageable, PagedResourcesAssembler<ModuleMetadata> assembler, @RequestParam("containerId") String containerId) { return maskSensitiveData(assembler.toResource( this.moduleMetadataRepository.findAllByContainerId(pageable, containerId), moduleMetadataResourceAssembler)); } /** * List the module metadata for all the modules with the given moduleId. * * @param pageable pagination information * @param assembler paged resource assembler * @param moduleId the module id of the module metadata to list * @return paged {@link ModuleMetadataResource} */ @RequestMapping(value = "", method = RequestMethod.GET, params = { "moduleId" }) @ResponseStatus(HttpStatus.OK) @ResponseBody public PagedResources<ModuleMetadataResource> listByModule(Pageable pageable, PagedResourcesAssembler<ModuleMetadata> assembler, @RequestParam("moduleId") String moduleId) { return maskSensitiveData(assembler.toResource( this.moduleMetadataRepository.findAllByModuleId(pageable, moduleId), moduleMetadataResourceAssembler)); } /** * List the module metadata for the given moduleId and deployed to the given containerId. * * @param containerId the container id of the container to choose * @param moduleId the module id of the module metadata to list * @return the {@link ModuleMetadataResource} of the module */ @RequestMapping(value = "", method = RequestMethod.GET, params = { "containerId", "moduleId" }) @ResponseStatus(HttpStatus.OK) @ResponseBody public ModuleMetadataResource listByContainerAndModuleId( @RequestParam("containerId") String containerId, @RequestParam("moduleId") String moduleId) { ModuleMetadata moduleMetadata = this.moduleMetadataRepository.findOne(containerId, moduleId); if (moduleMetadata == null) { throw new ModuleNotDeployedException(containerId, moduleId); } return maskSensitiveData(moduleMetadataResourceAssembler.toResource(moduleMetadata)); } /** * Will return a collection of {@link ModuleMetadata} that are associated with * the provided {@code jobname} request parameter. * * @param jobName parameter must not be null * @return Collection of {@link ModuleMetadata}, might be empty but never {@code null} */ @RequestMapping(value = "", method = RequestMethod.GET, params = { "jobname" }) @ResponseStatus(HttpStatus.OK) @ResponseBody public List<ModuleMetadataResource> displayForJobname(@RequestParam("jobname") String jobName) { final Iterable<ModuleMetadata> moduleMetadataIterable = this.moduleMetadataRepository.findAll(); final List<ModuleMetadata> moduleMetadataListToReturn = new ArrayList<ModuleMetadata>(); for (ModuleMetadata moduleMetadata : moduleMetadataIterable) { if (jobName.equals(moduleMetadata.getUnitName())) { moduleMetadataListToReturn.add(moduleMetadata); } } final List<ModuleMetadataResource> resources = moduleMetadataResourceAssembler.toResources(moduleMetadataListToReturn); maskSensitiveData(resources); return resources; } private ModuleMetadataResource maskSensitiveData(ModuleMetadataResource moduleMetadataResource) { PasswordUtils.maskPropertiesIfNecessary(moduleMetadataResource.getModuleOptions()); return moduleMetadataResource; } private PagedResources<ModuleMetadataResource> maskSensitiveData( PagedResources<ModuleMetadataResource> moduleMetadataResources) { maskSensitiveData(moduleMetadataResources.getContent()); return moduleMetadataResources; } private Collection<ModuleMetadataResource> maskSensitiveData( Collection<ModuleMetadataResource> moduleMetadataResources) { for (ModuleMetadataResource metadataResource : moduleMetadataResources) { maskSensitiveData(metadataResource); } return moduleMetadataResources; } }