Added integration for JMS
fixes gh-1141
This commit is contained in:
@@ -30,12 +30,10 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Component
|
||||
public class CamelStubMessages implements MessageVerifier<Message> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CamelStubMessages.class);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging;
|
||||
import org.springframework.cloud.contract.verifier.messaging.jms.ContractVerifierJmsConfiguration;
|
||||
import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -38,9 +39,9 @@ import org.springframework.context.annotation.Import;
|
||||
@Configuration
|
||||
@ConditionalOnClass(Message.class)
|
||||
@Import(CamelAutoConfiguration.class)
|
||||
@ConditionalOnProperty(name = "stubrunner.camel.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@AutoConfigureBefore(NoOpContractVerifierAutoConfiguration.class)
|
||||
@ConditionalOnProperty(name = "stubrunner.camel.enabled", havingValue = "true", matchIfMissing = true)
|
||||
@AutoConfigureBefore({ NoOpContractVerifierAutoConfiguration.class,
|
||||
ContractVerifierJmsConfiguration.class })
|
||||
public class ContractVerifierCamelConfiguration {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.cloud.contract.verifier.messaging.jms;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.ObjectMessage;
|
||||
import javax.jms.StreamMessage;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage;
|
||||
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging;
|
||||
import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(JmsTemplate.class)
|
||||
@ConditionalOnProperty(name = "stubrunner.jms.enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
@AutoConfigureBefore(NoOpContractVerifierAutoConfiguration.class)
|
||||
public class ContractVerifierJmsConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
MessageVerifier<Message> contractVerifierJmsMessageExchange(
|
||||
ObjectProvider<JmsTemplate> jmsTemplateProvider) {
|
||||
JmsTemplate jmsTemplate = jmsTemplateProvider.getIfAvailable(JmsTemplate::new);
|
||||
return new JmsStubMessages(jmsTemplate);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ContractVerifierMessaging<Message> contractVerifierJmsMessaging(
|
||||
MessageVerifier<Message> exchange) {
|
||||
return new ContractVerifierJmsHelper(exchange);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ContractVerifierJmsHelper extends ContractVerifierMessaging<Message> {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ContractVerifierJmsHelper.class);
|
||||
|
||||
ContractVerifierJmsHelper(MessageVerifier<Message> exchange) {
|
||||
super(exchange);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContractVerifierMessage convert(Message message) {
|
||||
try {
|
||||
Map<String, Object> headers = headers(message);
|
||||
return new ContractVerifierMessage(getPayload(message), headers);
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
log.warn("An exception occurred while trying to convert the JMS message", ex);
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> headers(Message message) throws JMSException {
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
if (message == null) {
|
||||
return headers;
|
||||
}
|
||||
Enumeration enumeration = message.getPropertyNames();
|
||||
while (enumeration.hasMoreElements()) {
|
||||
Object element = enumeration.nextElement();
|
||||
String asString = element.toString();
|
||||
Object property = message.getObjectProperty(asString);
|
||||
headers.put(asString, property);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Object getPayload(Message message) throws JMSException {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
else if (message instanceof TextMessage) {
|
||||
return ((TextMessage) message).getText();
|
||||
}
|
||||
else if (message instanceof StreamMessage) {
|
||||
return ((StreamMessage) message).readObject();
|
||||
}
|
||||
else if (message instanceof ObjectMessage) {
|
||||
return ((ObjectMessage) message).getObject();
|
||||
}
|
||||
return message.getBody(Object.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* https://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.cloud.contract.verifier.messaging.jms;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.JMSException;
|
||||
import javax.jms.Message;
|
||||
import javax.jms.Session;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.core.MessagePostProcessor;
|
||||
|
||||
class JmsStubMessages implements MessageVerifier<Message> {
|
||||
|
||||
private final JmsTemplate jmsTemplate;
|
||||
|
||||
JmsStubMessages(JmsTemplate jmsTemplate) {
|
||||
this.jmsTemplate = jmsTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Message message, String destination) {
|
||||
jmsTemplate.convertAndSend(destination, message, new ReplyToProcessor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message receive(String destination, long timeout, TimeUnit timeUnit) {
|
||||
jmsTemplate.setReceiveTimeout(timeUnit.toMillis(timeout));
|
||||
return jmsTemplate.receive(destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message receive(String destination) {
|
||||
return receive(destination, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object payload, Map headers, String destination) {
|
||||
jmsTemplate.send(destination, session -> {
|
||||
Message message = createMessage(session, payload);
|
||||
setHeaders(message, headers);
|
||||
return message;
|
||||
});
|
||||
}
|
||||
|
||||
private Message createMessage(Session session, Object payload) throws JMSException {
|
||||
if (payload instanceof String) {
|
||||
return session.createTextMessage((String) payload);
|
||||
}
|
||||
else if (payload instanceof byte[]) {
|
||||
BytesMessage bytesMessage = session.createBytesMessage();
|
||||
bytesMessage.writeBytes((byte[]) payload);
|
||||
return bytesMessage;
|
||||
}
|
||||
else if (payload instanceof Serializable) {
|
||||
return session.createObjectMessage((Serializable) payload);
|
||||
}
|
||||
return session.createMessage();
|
||||
}
|
||||
|
||||
private void setHeaders(Message message, Map<String, Object> headers) {
|
||||
for (Map.Entry<String, Object> entry : headers.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
try {
|
||||
if (value instanceof String) {
|
||||
message.setStringProperty(key, (String) value);
|
||||
}
|
||||
else if (value instanceof Boolean) {
|
||||
message.setBooleanProperty(key, (Boolean) value);
|
||||
}
|
||||
else {
|
||||
message.setObjectProperty(key, value);
|
||||
}
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ReplyToProcessor implements MessagePostProcessor {
|
||||
|
||||
@Override
|
||||
public Message postProcessMessage(Message message) throws JMSException {
|
||||
message.setStringProperty("requiresReply", "no");
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,4 +5,5 @@ org.springframework.cloud.contract.verifier.messaging.integration.ContractVerifi
|
||||
org.springframework.cloud.contract.verifier.messaging.amqp.ContractVerifierAmqpAutoConfiguration,\
|
||||
org.springframework.cloud.contract.verifier.messaging.amqp.RabbitMockConnectionFactoryAutoConfiguration,\
|
||||
org.springframework.cloud.contract.verifier.messaging.camel.ContractVerifierCamelConfiguration,\
|
||||
org.springframework.cloud.contract.verifier.messaging.jms.ContractVerifierJmsConfiguration,\
|
||||
org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierAutoConfiguration
|
||||
|
||||
Reference in New Issue
Block a user