Skip to content
Snippets Groups Projects
Commit 78422a10 authored by Rick Herrick's avatar Rick Herrick
Browse files

XNAT-4521 Moved MVC and REST controller to later in the process to allow

plugins to initialize before running scan with Swagger init.
parent 8dda1b31
No related branches found
No related tags found
No related merge requests found
package org.nrg.xapi.configuration;
import org.nrg.framework.annotations.XapiRestController;
import org.nrg.xnat.configuration.WebConfig;
import org.nrg.xnat.services.XnatAppInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Locale;
@Configuration
@EnableSwagger2
@ComponentScan({"org.nrg.xapi.rest", "org.nrg.xnat.spawner.configuration"})
public class RestApiConfig {
@Bean
public Docket api(final XnatAppInfo info, final MessageSource messageSource) {
_log.debug("Initializing the Swagger Docket object");
// TODO: When updating to Swagger 2.5.0 or later, remove the pathMapping("/xapi") call at the end.
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.withClassAnnotation(XapiRestController.class))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo(info, messageSource))
.pathMapping("/xapi");
}
private ApiInfo apiInfo(final XnatAppInfo info, final MessageSource messageSource) {
return new ApiInfo(getMessage(messageSource, "apiInfo.title"),
getMessage(messageSource, "apiInfo.description"),
info.getVersion(),
getMessage(messageSource, "apiInfo.termsOfServiceUrl"),
new Contact(getMessage(messageSource, "apiInfo.contactName"),
getMessage(messageSource, "apiInfo.contactUrl"),
getMessage(messageSource, "apiInfo.contactEmail")),
getMessage(messageSource, "apiInfo.license"),
getMessage(messageSource, "apiInfo.licenseUrl"));
}
private String getMessage(final MessageSource messageSource, final String messageId) {
return messageSource.getMessage(messageId, null, Locale.getDefault());
}
private static final Logger _log = LoggerFactory.getLogger(WebConfig.class);
}
package org.nrg.xapi.rest.dicom;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.nrg.config.exceptions.ConfigServiceException;
import org.nrg.framework.annotations.XapiRestController;
......@@ -78,7 +75,7 @@ public class AnonymizeApi extends AbstractXapiProjectRestController {
@ApiResponse(code = 403, message = "Insufficient permissions to modify the site-wide anonymization script settings."),
@ApiResponse(code = 500, message = "An unexpected error occurred.")})
@RequestMapping(value = "site/enabled", consumes = MediaType.TEXT_PLAIN_VALUE, method = RequestMethod.PUT)
public ResponseEntity<Void> setSiteWideAnonScriptEnabled(@RequestBody final boolean enable) throws ConfigServiceException {
public ResponseEntity<Void> setSiteWideAnonScriptEnabled(@ApiParam(value = "Whether the site-wide anonymization script should be enabled or disabled.", required = true) @RequestParam(required= false, defaultValue = "true") final boolean enable) throws ConfigServiceException {
final HttpStatus status = isPermitted();
if (status != null) {
return new ResponseEntity<>(status);
......@@ -119,7 +116,8 @@ public class AnonymizeApi extends AbstractXapiProjectRestController {
@ApiResponse(code = 404, message = "The specified project wasn't found."),
@ApiResponse(code = 500, message = "An unexpected error occurred.")})
@RequestMapping(value = "projects/{projectId}", consumes = MediaType.TEXT_PLAIN_VALUE, method = RequestMethod.PUT)
public ResponseEntity<Void> setProjectAnonScript(@PathVariable("projectId") final String projectId, @RequestBody final String script) throws NrgServiceException {
public ResponseEntity<Void> setProjectAnonScript(@ApiParam(value = "Indicates the ID of the project to be enabled or disabled.", required = true) @PathVariable("projectId") final String projectId,
@ApiParam(value = "Whether the specified project's anonymization script should be enabled or disabled.", required = true) @RequestBody final String script) throws NrgServiceException {
final HttpStatus status;
try {
status = canEditProject(projectId);
......@@ -161,7 +159,7 @@ public class AnonymizeApi extends AbstractXapiProjectRestController {
@ApiResponse(code = 403, message = "Insufficient permissions to modify the project-specific anonymization script settings."),
@ApiResponse(code = 500, message = "An unexpected error occurred.")})
@RequestMapping(value = "projects/{projectId}/enabled", consumes = MediaType.TEXT_PLAIN_VALUE, method = RequestMethod.PUT)
public ResponseEntity<Void> setProjectAnonScriptEnabled(@PathVariable("projectId") final String projectId, @RequestBody final boolean enable) throws NrgServiceException {
public ResponseEntity<Void> setProjectAnonScriptEnabled(@PathVariable("projectId") final String projectId, @RequestParam(required= false, defaultValue = "true") final boolean enable) throws NrgServiceException {
final HttpStatus status;
try {
status = canEditProject(projectId);
......
......@@ -36,8 +36,7 @@ import java.util.List;
"org.nrg.xdat.daos", "org.nrg.xdat.services.impl.hibernate", "org.nrg.xft.daos",
"org.nrg.xft.event.listeners", "org.nrg.xft.services", "org.nrg.xnat.configuration",
"org.nrg.xnat.daos", "org.nrg.xnat.event.listeners", "org.nrg.xnat.helpers.merge",
"org.nrg.xnat.initialization.tasks", "org.nrg.xnat.services.impl.hibernate",
"org.nrg.xnat.spawner.repositories"})
"org.nrg.xnat.initialization.tasks", "org.nrg.xnat.services.impl.hibernate"})
@Import({FeaturesConfig.class, ReactorConfig.class})
@ImportResource("WEB-INF/conf/mq-context.xml")
public class ApplicationConfig {
......
package org.nrg.xnat.configuration;
import org.nrg.framework.annotations.XapiRestController;
import org.nrg.xdat.preferences.SiteConfigPreferences;
import org.nrg.xnat.services.XnatAppInfo;
import org.nrg.xnat.spawner.configuration.SpawnerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
......@@ -28,22 +21,14 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import javax.xml.bind.Marshaller;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
@EnableWebMvc
@EnableSwagger2
@Import(SpawnerConfig.class)
@ComponentScan({"org.nrg.xapi.rest", "org.nrg.xnat.spawner.controllers"})
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
public void setJackson2ObjectMapperBuilder(final Jackson2ObjectMapperBuilder objectMapperBuilder) {
......@@ -51,7 +36,7 @@ public class WebConfig extends WebMvcConfigurerAdapter {
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("**/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
......@@ -63,6 +48,11 @@ public class WebConfig extends WebMvcConfigurerAdapter {
converters.add(stringHttpMessageConverter());
}
@Override
public void configurePathMatch(final PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
@Bean
public HttpMessageConverter<?> mappingJackson2HttpMessageConverter() {
return new MappingJackson2HttpMessageConverter(_objectMapperBuilder.build());
......@@ -83,11 +73,6 @@ public class WebConfig extends WebMvcConfigurerAdapter {
return new StandardServletMultipartResolver();
}
@Override
public void configurePathMatch(final PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
@Bean
public ViewResolver viewResolver() {
return new InternalResourceViewResolver() {{
......@@ -104,30 +89,9 @@ public class WebConfig extends WebMvcConfigurerAdapter {
}};
}
@Bean
public Docket api(final XnatAppInfo info, final MessageSource messageSource) {
_log.debug("Initializing the Swagger Docket object");
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.withClassAnnotation(XapiRestController.class)).paths(PathSelectors.any()).build().apiInfo(apiInfo(info, messageSource)).pathMapping("/xapi");
}
private ApiInfo apiInfo(final XnatAppInfo info, final MessageSource messageSource) {
return new ApiInfo(getMessage(messageSource, "apiInfo.title"),
getMessage(messageSource, "apiInfo.description"),
info.getVersion(),
getMessage(messageSource, "apiInfo.termsOfServiceUrl"),
new Contact(getMessage(messageSource, "apiInfo.contactName"),
getMessage(messageSource, "apiInfo.contactUrl"),
getMessage(messageSource, "apiInfo.contactEmail")),
getMessage(messageSource, "apiInfo.license"),
getMessage(messageSource, "apiInfo.licenseUrl"));
}
private String getMessage(final MessageSource messageSource, final String messageId) {
return messageSource.getMessage(messageId, null, Locale.getDefault());
}
private static final Logger _log = LoggerFactory.getLogger(WebConfig.class);
private static final Map<String, Object> MARSHALLER_PROPERTIES = new HashMap<String, Object>() {{ put(Marshaller.JAXB_FORMATTED_OUTPUT, true); }};
private static final Map<String, Object> MARSHALLER_PROPERTIES = new HashMap<String, Object>() {{
put(Marshaller.JAXB_FORMATTED_OUTPUT, true);
}};
private Jackson2ObjectMapperBuilder _objectMapperBuilder;
......@@ -135,5 +99,4 @@ public class WebConfig extends WebMvcConfigurerAdapter {
setClassesToBeBound(SiteConfigPreferences.class);
setMarshallerProperties(MARSHALLER_PROPERTIES);
}};
}
package org.nrg.xnat.initialization;
import org.nrg.xapi.configuration.RestApiConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(RestApiConfig.class)
public class ControllerConfig {
}
......@@ -5,8 +5,8 @@ import org.apache.axis.transport.http.AxisHTTPSessionListener;
import org.apache.axis.transport.http.AxisServlet;
import org.apache.commons.lang3.StringUtils;
import org.apache.turbine.Turbine;
import org.nrg.framework.exceptions.NrgServiceRuntimeException;
import org.nrg.framework.beans.XnatPluginBean;
import org.nrg.framework.exceptions.NrgServiceRuntimeException;
import org.nrg.xdat.servlet.XDATAjaxServlet;
import org.nrg.xdat.servlet.XDATServlet;
import org.nrg.xnat.restlet.servlet.XNATRestletServlet;
......@@ -69,14 +69,16 @@ public class XnatWebAppInitializer extends AbstractAnnotationConfigDispatcherSer
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
final List<Class<?>> configClasses = new ArrayList<>();
configClasses.add(RootConfig.class);
configClasses.addAll(getPluginConfigs());
configClasses.add(ControllerConfig.class);
return configClasses.toArray(new Class[configClasses.size()]);
}
@Override
protected Class<?>[] getServletConfigClasses() {
final List<Class<?>> configClasses = new ArrayList<>();
configClasses.addAll(getPluginConfigs());
return configClasses.toArray(new Class[configClasses.size()]);
return EMPTY_ARRAY;
}
@Override
......@@ -175,5 +177,7 @@ public class XnatWebAppInitializer extends AbstractAnnotationConfigDispatcherSer
}
private static final Logger _log = LoggerFactory.getLogger(XnatWebAppInitializer.class);
private static final Class<?>[] EMPTY_ARRAY = new Class<?>[0];
private ServletContext _context;
}
package org.nrg.xnat.spawner.controllers;
import org.apache.commons.lang3.StringUtils;
import org.nrg.xnat.spawner.entities.SpawnerElement;
import org.nrg.xnat.spawner.exceptions.InvalidElementIdException;
import org.nrg.xnat.spawner.services.SpawnerService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("SpringMVCViewInspection")
@Controller
@RequestMapping(value = "/spawner/manage", produces = "application/json")
public class ManageElementsController {
@RequestMapping
public ModelAndView getNamespaces() {
final List<String> namespaces = _service.getNamespaces();
return new ModelAndView("spawner/elements", "namespaces", namespaces);
}
@RequestMapping("elements")
public ModelAndView getDefaultElements() {
return getNamespacedElements(SpawnerElement.DEFAULT_NAMESPACE);
}
@RequestMapping("elements/{namespace}")
public ModelAndView getNamespacedElements(@PathVariable("namespace") final String namespace) {
final Map<String, Object> models = new HashMap<>();
models.put("namespace", namespace);
models.put("namespaces", _service.getNamespaces());
models.put("elements", _service.getDefaultElements());
return new ModelAndView("spawner/elements", models);
}
@RequestMapping(value = "element/{elementId}", method = RequestMethod.GET)
public ModelAndView getDefaultElement(@PathVariable final String elementId) {
return getNamespacedElement(SpawnerElement.DEFAULT_NAMESPACE, elementId);
}
@RequestMapping(value = "element/{namespace}/{elementId}", method = RequestMethod.GET)
public ModelAndView getNamespacedElement(@PathVariable("namespace") final String namespace, @PathVariable final String elementId) {
final SpawnerElement element = _service.retrieve(namespace, elementId);
return new ModelAndView("spawner/element", element == null ? "error" : "elementId", element == null ? "The ID element " + elementId + " was not found in the system." : elementId);
}
@RequestMapping(value = "element/{elementId}", method = RequestMethod.PUT)
public ModelAndView setDefaultElement(@PathVariable final String elementId, @RequestBody final SpawnerElement element) {
return setNamespacedElement(SpawnerElement.DEFAULT_NAMESPACE, elementId, element);
}
@RequestMapping(value = "element/{namespace}/{elementId}", method = RequestMethod.PUT)
public ModelAndView setNamespacedElement(@PathVariable final String namespace, @PathVariable final String elementId, @RequestBody final SpawnerElement element) {
if (element == null) {
return new ModelAndView("spawner/element", "error", "No valid spawner element was found in your submitted data.");
}
final SpawnerElement existing = _service.retrieve(elementId);
final boolean isModElementId = !StringUtils.equals(existing.getElementId(), element.getElementId());
final boolean isModYaml = !StringUtils.equals(existing.getYaml(), element.getYaml());
if (isModElementId || isModYaml) {
if (isModElementId) {
try {
existing.setElementId(element.getElementId());
} catch (InvalidElementIdException e) {
return new ModelAndView("spawner/element", "error", "The element ID " + element.getElementId() + " in your submitted data is invalid. Check for duplicated or invalid values.");
}
}
if (isModYaml) {
existing.setYaml(element.getYaml());
}
_service.update(existing);
return new ModelAndView("spawner/element", "element", element);
}
return new ModelAndView("spawner/element", "error", "The submitted spawner element wasn't modified, not updated.");
}
@Inject
private SpawnerService _service;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment