Spring Integration
  1. Spring Integration
  2. INT-2352

AMMR - Add @ManagedOperation to setChannelMappings()

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Complete
    • Affects Version/s: 2.1 RC2
    • Fix Version/s: 4.0 RC1
    • Component/s: None
    • Labels:

      Description

      It would be useful if the <control-bus/> could be used to replace the mappings in a dynamic router.

      Consider...

      
      	<int:converter ref="stringToMap" />
      	
      	<bean id="stringToMap" class="org.springframework.integration.router.config.StringToMapConverter" />
      	
      	<int:channel id="in" />
      
      	<int:router id="router" input-channel="in" ref="myRouter" resolution-required="false"/>
      
      	<bean id="myRouter" class="org.springframework.integration.router.HeaderValueRouter">
      		<constructor-arg value="routing.header" />
      	</bean>
      	
      	<int:channel id="control" />
      	
      	<int:control-bus input-channel="control" />
      		
      	<int:channel id="qux">
      		<int:queue />
      	</int:channel>
      

      We can add/remove mappings using the control bus, but we cannot establish a new set of mappings, thus...

      @ContextConfiguration
      @RunWith(SpringJUnit4ClassRunner.class)
      public class UpdateMappingsTests {
      
      	@Autowired
      	private MessageChannel control;
      	
      	@Autowired
      	private MessageChannel in;
      	
      	@Autowired 
      	private QueueChannel qux;
      	
      	@Test
      	public void test() {
      		control.send(new GenericMessage<String>("@myRouter.setChannelMappings('foo=bar, baz=qux')"));
      		Message<?> message = MessageBuilder.withPayload("Hello, world!")
      				.setHeader("routing.header", "baz").build();
      		in.send(message );
      		assertNotNull(qux.receive());
      	}
      
      }
      
      
      public class StringToMapConverter implements Converter<String, Map<String, String>> {
      
      	public Map<String, String> convert(String source) {
      		Map<String, String> map = new HashMap<String, String>();
      		String[] entries = source.split(",");
      		for (String entry : entries) {
      			String[] keyVal = entry.split("=");
      			map.put(keyVal[0].trim(), keyVal[1].trim());
      		}
      		return map;
      	}
      
      }
      

      Caused by: org.springframework.expression.EvaluationException: The method 'public void org.springframework.integration.router.AbstractMappingMessageRouter.setChannelMappings(java.util.Map)' is not supported by this command processor. If using the Control Bus, consider adding @ManagedOperation or @ManagedAttribute.

      Simply adding @ManagedOperation to setChannelMappings() enables this capability (using a custom converter).

      I have the fix and tests; not sure if we want to include (a more robust version of) the converter. Perhaps this converter is a candidate for core?

        Issue Links

          Activity

          Hide
          Mark Fisher added a comment -

          So, you think we might want to actually include that converter within our defaults (when we create the ConversionService), or simply make it available as an option to be defined as an explicit bean?

          Show
          Mark Fisher added a comment - So, you think we might want to actually include that converter within our defaults (when we create the ConversionService), or simply make it available as an option to be defined as an explicit bean?
          Hide
          Gary Russell added a comment -

          Hadn't really thought it through that far. I started out thinking the AMMR method should be exposed via <control-bus/>, then was a little surprised we didn't have a simple string to map converter in Core.

          Right now, it's just part of my test case; it would need to be a little more robust as a real component.

          Show
          Gary Russell added a comment - Hadn't really thought it through that far. I started out thinking the AMMR method should be exposed via <control-bus/>, then was a little surprised we didn't have a simple string to map converter in Core. Right now, it's just part of my test case; it would need to be a little more robust as a real component.
          Hide
          Gary Russell added a comment -

          Be sure to add it to the MappingMessageRouterManagement interface too (see INT-2413), and add test in JMX module.

          Show
          Gary Russell added a comment - Be sure to add it to the MappingMessageRouterManagement interface too (see INT-2413 ), and add test in JMX module.
          Hide
          Artem Bilan added a comment -

          Can't we use here out of the box default StringToPropertiesConverter: https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/test/java/org/springframework/core/convert/support/DefaultConversionTests.java#L680 ?

          Of course, we should change setChannelMappings signature to use Properties, or just provide one more method.

          From other side it would be great if SpEL would support inline map, as it looks in Groovy: http://groovy.codehaus.org/JN1035-Maps.
          Although we can go ahead with StringToMapConverter with that Groovy style and it will work from JMX, too.

          Show
          Artem Bilan added a comment - Can't we use here out of the box default StringToPropertiesConverter : https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/test/java/org/springframework/core/convert/support/DefaultConversionTests.java#L680 ? Of course, we should change setChannelMappings signature to use Properties , or just provide one more method. From other side it would be great if SpEL would support inline map , as it looks in Groovy: http://groovy.codehaus.org/JN1035-Maps . Although we can go ahead with StringToMapConverter with that Groovy style and it will work from JMX, too.
          Hide
          Gary Russell added a comment -

          Thanks, Artem.

          Add a method that accepts properties and use a StringToProperties converter to allow an atomic reset of the routes.

          Show
          Gary Russell added a comment - Thanks, Artem. Add a method that accepts properties and use a StringToProperties converter to allow an atomic reset of the routes.

            People

            • Assignee:
              Gary Russell
              Reporter:
              Gary Russell
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 0.25d
                0.25d
                Remaining:
                Remaining Estimate - 0.25d
                0.25d
                Logged:
                Time Spent - Not Specified
                Not Specified