org.springframework.amqp.remoting.client.AmqpClientInterceptor Maven / Gradle / Ivy
/*
* Copyright 2002-2014 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.amqp.remoting.client;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.remoting.service.AmqpInvokerServiceExporter;
import org.springframework.remoting.RemoteProxyFailureException;
import org.springframework.remoting.support.DefaultRemoteInvocationFactory;
import org.springframework.remoting.support.RemoteAccessor;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationFactory;
import org.springframework.remoting.support.RemoteInvocationResult;
/**
* {@link org.aopalliance.intercept.MethodInterceptor} for accessing RMI-style AMQP services.
*
* @author David Bilge
* @author Gary Russell
* @since 1.2
* @see AmqpInvokerServiceExporter
* @see AmqpProxyFactoryBean
* @see org.springframework.remoting.RemoteAccessException
*/
public class AmqpClientInterceptor extends RemoteAccessor implements MethodInterceptor {
private AmqpTemplate amqpTemplate;
private String routingKey = null;
private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory();
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
RemoteInvocation remoteInvocation = getRemoteInvocationFactory().createRemoteInvocation(invocation);
Object rawResult;
if (getRoutingKey() == null) {
// Use the template's default routing key
rawResult = amqpTemplate.convertSendAndReceive(remoteInvocation);
}
else {
rawResult = amqpTemplate.convertSendAndReceive(routingKey, remoteInvocation);
}
if (rawResult == null) {
throw new RemoteProxyFailureException("No reply received - perhaps a timeout in the template?", null);
}
else if (!(rawResult instanceof RemoteInvocationResult)) {
throw new RemoteProxyFailureException("Expected a result of type "
+ RemoteInvocationResult.class.getCanonicalName() + " but found "
+ rawResult.getClass().getCanonicalName(), null);
}
RemoteInvocationResult result = (RemoteInvocationResult) rawResult;
return result.recreate();
}
public AmqpTemplate getAmqpTemplate() {
return amqpTemplate;
}
/**
* The AMQP template to be used for sending messages and receiving results. This class is using "Request/Reply" for
* sending messages as described in the Spring-AMQP
* documentation.
*
* @param amqpTemplate The amqp template.
*/
public void setAmqpTemplate(AmqpTemplate amqpTemplate) {
this.amqpTemplate = amqpTemplate;
}
public String getRoutingKey() {
return routingKey;
}
/**
* The routing key to send calls to the service with. Use this to route the messages to a specific queue on the
* broker. If not set, the {@link AmqpTemplate}'s default routing key will be used.
*
* This property is useful if you want to use the same AmqpTemplate to talk to multiple services.
*
* @param routingKey The routing key.
*/
public void setRoutingKey(String routingKey) {
this.routingKey = routingKey;
}
public RemoteInvocationFactory getRemoteInvocationFactory() {
return remoteInvocationFactory;
}
/**
* Set the RemoteInvocationFactory to use for this accessor. Default is a {@link DefaultRemoteInvocationFactory}.
*
* A custom invocation factory can add further context information to the invocation, for example user credentials.
*
* @param remoteInvocationFactory The remote invocation factory.
*/
public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) {
this.remoteInvocationFactory = remoteInvocationFactory;
}
}