I'm trying to write an integration test for a sink I'm creating for Spring XD. Here is my ModuleConfiguration.java
@Configuration
@EnableIntegration
public class ModuleConfiguration {
private OAuth2AccessToken token;
@Bean
public MessageChannel input() {
return new DirectChannel();
}
@Bean
protected OAuth2ProtectedResourceDetails resource() {
BaseOAuth2ProtectedResourceDetails resource = new BaseOAuth2ProtectedResourceDetails();
resource.setAccessTokenUri("https://xxxxxxxxxxx");
resource.setClientId("id");
resource.setClientSecret("secret");
resource.setGrantType("authorization_code");
return resource;
}
@Bean
public OAuth2RestTemplate oAuthTemplate() {
AccessTokenRequest atr = new DefaultAccessTokenRequest();
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(atr));
return restTemplate;
}
@Bean
public HeaderMapper<HttpHeaders> headerMapper() {
HeaderMapper<HttpHeaders> mapper = new DefaultHttpHeaderMapper();
HttpHeaders headers = new HttpHeaders();
token = oAuthTemplate().getAccessToken();
String authHeader = "Bearer " + token.getValue();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", authHeader);
mapper.toHeaders(headers);
return mapper;
}
@ServiceActivator(inputChannel="inputChannel")
@Bean
public MessageHandler httpout() {
HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("https://yyyyyyyyy");
handler.setCharset("UTF-8");
handler.setHttpMethod(HttpMethod.POST);
handler.setHeaderMapper(headerMapper());
return handler;
}
}
I implemented the test the same way that a test for a processor is written, and tell spring xd that this module is a processor because that's what it expects. Not sure, but I don't think that matters, the exception I'm getting has to do with OAuth. Here is SinkTest.java
public class SinkTest {
private static SingleNodeApplication application;
private static int RECEIVE_TIMEOUT = 5000;
private static String moduleName = "oauth-sink";
@BeforeClass
public static void setUp() {
application = new SingleNodeApplication().run();
SingleNodeIntegrationTestSupport singleNodeIntegrationTestSupport = new SingleNodeIntegrationTestSupport(
application);
singleNodeIntegrationTestSupport
.addModuleRegistry(new SingletonModuleRegistry(ModuleType.processor, moduleName));
}
@Test
public void test() {
String streamName = "sinkTest";
byte[] encoded = null;
String data = null;
try {
encoded = Files.readAllBytes(Paths.get("src/test/resources/dataunit.json"));
data = new String(encoded, "utf-8");
} catch (IOException e) {
e.printStackTrace();
fail("Exception thrown");
}
String processingChainUnderTest = moduleName;
SingleNodeProcessingChain chain = chain(application, streamName, processingChainUnderTest);
chain.sendPayload(data);
@SuppressWarnings("unchecked")
List<Map<String, Object>> result = (List<Map<String, Object>>) chain.receivePayload(RECEIVE_TIMEOUT);
// Unbind the source and sink channels from the message bus
chain.destroy();
// an exception is thrown by zookeeper when the spring xd container shuts down after the test passes
}
}
I get an exception on this line of my ModuleConfiguration
token = oAuthTemplate().getAccessToken();
Caused by: error="access_denied", error_description="Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it."
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:146)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:118)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
If I use client_credentials for the GrantType in ModuleConfiguration like this
@Bean
protected OAuth2ProtectedResourceDetails resource() {
BaseOAuth2ProtectedResourceDetails resource = new ClientCredentialsResourceDetails();
resource.setAccessTokenUri("https://xxxxxxx");
resource.setClientId("id");
resource.setClientSecret("secret");
resource.setGrantType("client_credentials");
return resource;
}
I get
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:107)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
... 29 more
What is the correct grant type to use when I just have clientId and secret? Is there something missing from my ModuleConfiguration?
Update
I changed the inputChannel in @ServiceActivator
to the correct value and I am now getting the same exception as before with BaseOAuth2ProtectedResourceDetails
. Now getting a different exception with ClientCredentialsResourceDetails
Caused by: java.lang.IllegalArgumentException: Map has no value for 'object-type'
at org.springframework.web.util.UriComponents$MapTemplateVariables.getValue(UriComponents.java:276)
at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:221)
at org.springframework.web.util.HierarchicalUriComponents$FullPathComponent.expand(HierarchicalUriComponents.java:650)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:319)
at org.springframework.web.util.HierarchicalUriComponents.expandInternal(HierarchicalUriComponents.java:46)
at org.springframework.web.util.UriComponents.expand(UriComponents.java:152)
at org.springframework.web.util.UriComponentsBuilder.buildAndExpand(UriComponentsBuilder.java:376)
at org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler.handleRequestMessage(HttpRequestExecutingMessageHandler.java:376)
... 35 more