diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java index ddb830e12e..3d51dc40ff 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -79,6 +79,8 @@ public abstract class IntegrationContextUtils { public static final String INTEGRATION_LIFECYCLE_ROLE_CONTROLLER = "integrationLifecycleRoleController"; + public static final String INTEGRATION_GRAPH_SERVER_BEAN_NAME = "integrationGraphServer"; + /** * @param beanFactory BeanFactory for lookup, must not be null. * @return The {@link MetadataStore} bean whose name is "metadataStore". diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/EnableIntegrationGraphController.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/EnableIntegrationGraphController.java new file mode 100644 index 0000000000..d44ce5b9f9 --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/EnableIntegrationGraphController.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 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.integration.http.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Import; +import org.springframework.core.annotation.AliasFor; +import org.springframework.integration.http.management.IntegrationGraphController; +import org.springframework.integration.http.support.HttpContextUtils; + +/** + * Enables the {@link IntegrationGraphController} if {@code DispatcherServlet} is present in the classpath. + * + * @author Artem Bilan + * + * @since 4.3 + * + * @see IntegrationGraphController + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Import(IntegrationGraphControllerRegistrarImportSelector.class) +public @interface EnableIntegrationGraphController { + + /** + * Specify the Request Mapping path for the {@link IntegrationGraphController}. + * Defaults to {@value HttpContextUtils#GRAPH_CONTROLLER_DEFAULT_PATH}. + * @return The Request Mapping path for the {@link IntegrationGraphController} + */ + @AliasFor("path") + String value() default HttpContextUtils.GRAPH_CONTROLLER_DEFAULT_PATH; + + /** + * Specify the Request Mapping path for the {@link IntegrationGraphController}. + * Defaults to {@value HttpContextUtils#GRAPH_CONTROLLER_DEFAULT_PATH}. + * @return The Request Mapping path for the {@link IntegrationGraphController} + */ + @AliasFor("value") + String path() default HttpContextUtils.GRAPH_CONTROLLER_DEFAULT_PATH; + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpIntegrationConfigurationInitializer.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpIntegrationConfigurationInitializer.java index da431c3a99..4668cbae4f 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpIntegrationConfigurationInitializer.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpIntegrationConfigurationInitializer.java @@ -28,7 +28,6 @@ import org.springframework.integration.config.IntegrationConfigurationInitialize import org.springframework.integration.config.xml.IntegrationNamespaceUtils; import org.springframework.integration.http.inbound.IntegrationRequestMappingHandlerMapping; import org.springframework.integration.http.support.HttpContextUtils; -import org.springframework.util.ClassUtils; /** * The HTTP Integration infrastructure {@code beanFactory} initializer. @@ -40,9 +39,6 @@ public class HttpIntegrationConfigurationInitializer implements IntegrationConfi private static final Log logger = LogFactory.getLog(HttpIntegrationConfigurationInitializer.class); - private static final boolean servletPresent = ClassUtils.isPresent("javax.servlet.Servlet", - HttpIntegrationConfigurationInitializer.class.getClassLoader()); - @Override public void initialize(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (beanFactory instanceof BeanDefinitionRegistry) { @@ -65,7 +61,8 @@ public class HttpIntegrationConfigurationInitializer implements IntegrationConfi * the HTTP server components. */ private void registerRequestMappingHandlerMappingIfNecessary(BeanDefinitionRegistry registry) { - if (servletPresent && !registry.containsBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME)) { + if (HttpContextUtils.SERVLET_PRESENT && + !registry.containsBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME)) { BeanDefinitionBuilder requestMappingBuilder = BeanDefinitionBuilder.genericBeanDefinition(IntegrationRequestMappingHandlerMapping.class); requestMappingBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpNamespaceHandler.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpNamespaceHandler.java index 2bcdfc130c..bf39895fff 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpNamespaceHandler.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2016 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. @@ -22,15 +22,18 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa * Namespace handler for Spring Integration's http namespace. * * @author Mark Fisher + * @author Artem Bilan + * * @since 1.0.2 */ public class HttpNamespaceHandler extends AbstractIntegrationNamespaceHandler { public void init() { - this.registerBeanDefinitionParser("inbound-channel-adapter", new HttpInboundEndpointParser(false)); - this.registerBeanDefinitionParser("inbound-gateway", new HttpInboundEndpointParser(true)); - this.registerBeanDefinitionParser("outbound-channel-adapter", new HttpOutboundChannelAdapterParser()); - this.registerBeanDefinitionParser("outbound-gateway", new HttpOutboundGatewayParser()); + registerBeanDefinitionParser("inbound-channel-adapter", new HttpInboundEndpointParser(false)); + registerBeanDefinitionParser("inbound-gateway", new HttpInboundEndpointParser(true)); + registerBeanDefinitionParser("outbound-channel-adapter", new HttpOutboundChannelAdapterParser()); + registerBeanDefinitionParser("outbound-gateway", new HttpOutboundGatewayParser()); + registerBeanDefinitionParser("graph-controller", new IntegrationGraphControllerParser()); } } diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerParser.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerParser.java new file mode 100644 index 0000000000..47042ffdb8 --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerParser.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 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.integration.http.config; + +import java.util.Collections; +import java.util.Map; + +import org.w3c.dom.Element; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.core.type.StandardAnnotationMetadata; +import org.springframework.integration.http.support.HttpContextUtils; + +/** + * The {@link BeanDefinitionParser} for the {@code } component. + * @author Artem Bilan + * + * @since 4.3 + */ +public class IntegrationGraphControllerParser implements BeanDefinitionParser { + + private final IntegrationGraphControllerRegistrar graphControllerRegistrar = + new IntegrationGraphControllerRegistrar(); + + @Override + public BeanDefinition parse(final Element element, ParserContext parserContext) { + if (HttpContextUtils.SERVLET_PRESENT) { + this.graphControllerRegistrar.registerBeanDefinitions( + new StandardAnnotationMetadata(IntegrationGraphControllerParser.class) { + + @Override + public Map getAnnotationAttributes(String annotationType) { + return Collections.singletonMap("value", element.getAttribute("path")); + } + + }, parserContext.getRegistry()); + } + else { + parserContext.getReaderContext().warning("The 'IntegrationGraphController' isn't registered " + + "with the application context because" + + " there is no 'org.springframework.web.servlet.DispatcherServlet' in the classpath.", element); + } + + return null; + } + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrar.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrar.java new file mode 100644 index 0000000000..da0fcb01fc --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrar.java @@ -0,0 +1,101 @@ +/* + * Copyright 2016 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.integration.http.config; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.integration.context.IntegrationContextUtils; +import org.springframework.integration.http.management.IntegrationGraphController; +import org.springframework.integration.http.support.HttpContextUtils; +import org.springframework.integration.support.management.graph.IntegrationGraphServer; + +/** + * @author Artem Bilan + * @since 4.3 + */ +class IntegrationGraphControllerRegistrar implements ImportBeanDefinitionRegistrar { + + @Override + public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { + Map annotationAttributes = + importingClassMetadata.getAnnotationAttributes(EnableIntegrationGraphController.class.getName()); + + if (!registry.containsBeanDefinition(IntegrationContextUtils.INTEGRATION_GRAPH_SERVER_BEAN_NAME)) { + registry.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_GRAPH_SERVER_BEAN_NAME, + new RootBeanDefinition(IntegrationGraphServer.class)); + } + + if (!registry.containsBeanDefinition(HttpContextUtils.GRAPH_CONTROLLER_BEAN_NAME)) { + AbstractBeanDefinition controllerPropertiesPopulator = + BeanDefinitionBuilder.genericBeanDefinition(GraphControllerPropertiesPopulator.class) + .addConstructorArgValue(annotationAttributes) + .setRole(BeanDefinition.ROLE_INFRASTRUCTURE) + .getBeanDefinition(); + BeanDefinitionReaderUtils.registerWithGeneratedName(controllerPropertiesPopulator, registry); + + BeanDefinition graphController = + BeanDefinitionBuilder.genericBeanDefinition(IntegrationGraphController.class) + .addConstructorArgReference(IntegrationContextUtils.INTEGRATION_GRAPH_SERVER_BEAN_NAME) + .getBeanDefinition(); + + registry.registerBeanDefinition(HttpContextUtils.GRAPH_CONTROLLER_BEAN_NAME, graphController); + } + } + + private static final class GraphControllerPropertiesPopulator + implements BeanFactoryPostProcessor, EnvironmentAware { + + private final Map properties = new HashMap(); + + private GraphControllerPropertiesPopulator(Map annotationAttributes) { + Object graphControllerPath = annotationAttributes.get(AnnotationUtils.VALUE); + this.properties.put(HttpContextUtils.GRAPH_CONTROLLER_PATH_PROPERTY, graphControllerPath); + } + + @Override + public void setEnvironment(Environment environment) { + ((ConfigurableEnvironment) environment) + .getPropertySources() + .addLast(new MapPropertySource(HttpContextUtils.GRAPH_CONTROLLER_BEAN_NAME + "_properties", + this.properties)); + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + + } + + } + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrarImportSelector.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrarImportSelector.java new file mode 100644 index 0000000000..2e087c45d8 --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrarImportSelector.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 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.integration.http.config; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.context.annotation.ImportSelector; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.integration.http.support.DefaultHttpHeaderMapper; +import org.springframework.integration.http.support.HttpContextUtils; + +/** + * @author Artem Bilan + * @since 4.3 + */ +class IntegrationGraphControllerRegistrarImportSelector implements ImportSelector { + + private static final Log logger = LogFactory.getLog(DefaultHttpHeaderMapper.class); + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + if (HttpContextUtils.SERVLET_PRESENT) { + return new String[] { IntegrationGraphControllerRegistrar.class.getName() }; + } + else { + logger.warn("The 'IntegrationGraphController' isn't registered with the application context because" + + " there is no 'org.springframework.web.servlet.DispatcherServlet' in the classpath."); + return new String[0]; + } + } + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/management/IntegrationGraphController.java b/spring-integration-http/src/main/java/org/springframework/integration/http/management/IntegrationGraphController.java new file mode 100644 index 0000000000..f6ade879ea --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/management/IntegrationGraphController.java @@ -0,0 +1,57 @@ +/* + * Copyright 2016 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.integration.http.management; + +import org.springframework.integration.http.support.HttpContextUtils; +import org.springframework.integration.support.management.graph.Graph; +import org.springframework.integration.support.management.graph.IntegrationGraphServer; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * The REST Controller to provide the management API over {@link IntegrationGraphServer}. + * + * @author Artem Bilan + * + * @since 4.3 + */ +@RestController +@RequestMapping(IntegrationGraphController.REQUEST_MAPPING_PATH_VARIABLE) +public class IntegrationGraphController { + + final static String REQUEST_MAPPING_PATH_VARIABLE = + "${" + HttpContextUtils.GRAPH_CONTROLLER_PATH_PROPERTY + ":" + + HttpContextUtils.GRAPH_CONTROLLER_DEFAULT_PATH + "}"; + + private final IntegrationGraphServer integrationGraphServer; + + public IntegrationGraphController(IntegrationGraphServer integrationGraphServer) { + this.integrationGraphServer = integrationGraphServer; + } + + @GetMapping(name = "getGraph") + public Graph getGraph() { + return this.integrationGraphServer.getGraph(); + } + + @GetMapping(path = "/refresh", name = "refreshGraph") + public Graph refreshGraph() { + return this.integrationGraphServer.rebuild(); + } + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/management/package-info.java b/spring-integration-http/src/main/java/org/springframework/integration/http/management/package-info.java new file mode 100644 index 0000000000..44f0faf60d --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/management/package-info.java @@ -0,0 +1,4 @@ +/** + * Provides classes related to management support. + */ +package org.springframework.integration.http.management; diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/support/HttpContextUtils.java b/spring-integration-http/src/main/java/org/springframework/integration/http/support/HttpContextUtils.java index a142aed857..5617180436 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/support/HttpContextUtils.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/support/HttpContextUtils.java @@ -16,8 +16,11 @@ package org.springframework.integration.http.support; +import org.springframework.util.ClassUtils; + /** - * Utility class for accessing HTTP integration components from the {@link org.springframework.beans.factory.BeanFactory}. + * Utility class for accessing HTTP integration components + * from the {@link org.springframework.beans.factory.BeanFactory}. * * @author Artem Bilan * @author Gary Russell @@ -29,9 +32,34 @@ public final class HttpContextUtils { super(); } + /** + * The {@code boolean} flag to indicate if the {@code org.springframework.web.servlet.DispatcherServlet} + * is present in the CLASSPATH to allow to register the Integration server components, + * e.g. {@code IntegrationGraphController}. + */ + public static final boolean SERVLET_PRESENT = + ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", + HttpContextUtils.class.getClassLoader()); + /** * @see org.springframework.integration.http.config.HttpInboundEndpointParser */ public static final String HANDLER_MAPPING_BEAN_NAME = "integrationRequestMappingHandlerMapping"; + /** + * Represents the environment property for the {@code IntegrationGraphController} request mapping path. + */ + public static final String GRAPH_CONTROLLER_PATH_PROPERTY = + "spring.integration.graph.controller.request.mapping.path"; + + /** + * Represents the default request mapping path for the {@code IntegrationGraphController}. + */ + public static final String GRAPH_CONTROLLER_DEFAULT_PATH = "/integration"; + + /** + * Represents the bean name for the default {@code IntegrationGraphController}. + */ + public static final String GRAPH_CONTROLLER_BEAN_NAME = "integrationGraphController"; + } diff --git a/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.3.xsd b/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.3.xsd index 522c1f2479..6a166e437b 100644 --- a/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.3.xsd +++ b/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-4.3.xsd @@ -492,6 +492,28 @@ + + + + Configures a + 'org.springframework.integration.http.management.IntegrationGraphController' bean + to expose a REST API for the + 'org.springframework.integration.support.management.graph.IntegrationGraphServer' bean. + Note: Spring Web MVC must be present in the application to enable and register this component. + + + + + + + The root request mapping path for the 'IntegrationGraphController'. + Defaults to /integration. + + + + + + + + + + + + + diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/management/IntegrationGraphControllerTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/management/IntegrationGraphControllerTests.java new file mode 100644 index 0000000000..22d3350be3 --- /dev/null +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/management/IntegrationGraphControllerTests.java @@ -0,0 +1,146 @@ +/* + * Copyright 2016 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.integration.http.management; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.handler; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.integration.channel.DirectChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.http.config.EnableIntegrationGraphController; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.HandlerAdapter; +import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +/** + * @author Artem Bilan + * @since 4.3 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@WebAppConfiguration +public class IntegrationGraphControllerTests { + + @Autowired + private WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void testIntegrationGraphGet() throws Exception { + this.mockMvc.perform(get("/testIntegration") + .accept(MediaType.parseMediaType("application/json;charset=UTF-8"))) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/json;charset=UTF-8")) + .andExpect(handler().handlerType(IntegrationGraphController.class)) + .andExpect(handler().methodName("getGraph")) + .andExpect(jsonPath("$.nodes..name") + .value(Matchers.containsInAnyOrder("nullChannel", "errorChannel", + "_org.springframework.integration.errorLogger"))) + .andExpect(jsonPath("$.links").exists()); + } + + @Test + public void testIntegrationGraphControllerParser() throws Exception { + ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( + "IntegrationGraphControllerParserTests-context.xml", getClass()); + + + + HandlerMapping handlerMapping = + context.getBean(RequestMappingHandlerMapping.class.getName(), HandlerMapping.class); + + HandlerAdapter handlerAdapter = context.getBean(RequestMappingHandlerAdapter.class); + + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("GET"); + request.setRequestURI("/foo"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + HandlerExecutionChain executionChain = handlerMapping.getHandler(request); + assertNotNull(executionChain); + + Object handler = executionChain.getHandler(); + + handlerAdapter.handle(request, response, handler); + assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertThat(response.getContentAsString(), containsString("\"name\":\"nullChannel\",")); + assertThat(response.getContentAsString(), not(containsString("\"name\":\"myChannel\","))); + + context.getBeanFactory().registerSingleton("myChannel", new DirectChannel()); + + request = new MockHttpServletRequest(); + request.setMethod("GET"); + request.setRequestURI("/foo/refresh"); + response = new MockHttpServletResponse(); + + executionChain = handlerMapping.getHandler(request); + assertNotNull(executionChain); + + handler = executionChain.getHandler(); + + handlerAdapter.handle(request, response, handler); + assertEquals(HttpStatus.OK.value(), response.getStatus()); + assertThat(response.getContentAsString(), containsString("\"name\":\"myChannel\",")); + + context.close(); + } + + @Configuration + @EnableWebMvc + @EnableIntegration + @EnableIntegrationGraphController(path = "/testIntegration") + public static class ContextConfiguration { + + } + +} diff --git a/spring-integration-http/src/test/resources/.svnignore b/spring-integration-http/src/test/resources/.svnignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-integration-http/src/test/resources/log4j.properties b/spring-integration-http/src/test/resources/log4j.properties new file mode 100644 index 0000000000..3cf693eac4 --- /dev/null +++ b/spring-integration-http/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +log4j.rootCategory=WARN, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss.SSS} %-5p [%t][%c] %m%n + +#log4j.category.org.springframework=DEBUG +log4j.category.org.springframework.integration=WARN +log4j.category.org.springframework.integration.http=WARN