All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avanza.astrix.gs.remoting.GsRoutingStrategy Maven / Gradle / Ivy

There is a newer version: 2.0.6
Show newest version
/*
 * Copyright 2014 Avanza Bank AB
 *
 * 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 com.avanza.astrix.gs.remoting;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.openspaces.remoting.Routing;

import com.avanza.astrix.core.AstrixBroadcast;
import com.avanza.astrix.core.remoting.Router;
import com.avanza.astrix.core.remoting.RoutingStrategy;
import com.avanza.astrix.remoting.client.AmbiguousRoutingException;
import com.avanza.astrix.remoting.client.AnnotatedArgumentInstanceRouter;
import com.avanza.astrix.remoting.client.AnnotatedArgumentRouter;
import com.avanza.astrix.remoting.client.BroadcastRouter;
import com.avanza.astrix.remoting.client.DefaultAstrixRoutingStrategy;
import com.avanza.astrix.remoting.client.PropertyOnAnnotatedArgumentRoutingStrategy;
import com.avanza.astrix.remoting.util.RoutingKeyMethodCache;
import com.gigaspaces.annotation.pojo.SpaceRouting;
/**
 * Provides a routing strategy compatible with the routing used by native 
 * gigaspaces remoting, (@Routing annotated arguments).
 * 
 * @author Elias Lindholm
 *
 */
public class GsRoutingStrategy implements RoutingStrategy {
	
	private static final RoutingKeyMethodCache routingKeyMethodCache = new RoutingKeyMethodCache<>(SpaceRouting.class);

	@Override
	public Router create(Method serviceMethod) {
		return createRoutingStrategy(serviceMethod);
	}
	
	private Router createRoutingStrategy(Method m) {
		Router result = new DefaultAstrixRoutingStrategy().create(m);
		if (result != null) {
			return result;
		}
		result = lookForRoutingAnnotationInMethodSignature(m);
		if (result != null) {
			return result;
		}
		result = lookForRoutingAnnotationOnMethodArguments(m);
		if (result != null) {
			return result;
		}
		if (m.getAnnotation(AstrixBroadcast.class) == null) {
			throw new AmbiguousRoutingException(String.format("Ambiguous routing. No routing argument defined in method signature or on method " +
					"arguments and method not annotated with @AstrixBroadcast. serviceMethod=%s", m.toString()));
		}
		return new BroadcastRouter();
	}

	private Router lookForRoutingAnnotationOnMethodArguments(Method m) {
		Router result = null;
		for (int argumentIndex = 0; argumentIndex < m.getParameterTypes().length; argumentIndex++) {
			Method routingKeyMethod = routingKeyMethodCache.getRoutingKeyMethod(m.getParameterTypes()[argumentIndex]);
			if (routingKeyMethod != null) {
				if (result != null) {
					throw new AmbiguousRoutingException(String.format("Ambiguous routing, multiple arguments with @SpaceRouting annotated methods." +
							" Use @Routing on one service argument to identify routing method, or @AstrixBroadcast for broadcast" +
							" operations. service method=%s", m.toString()));
				}
				result = new AnnotatedArgumentInstanceRouter(argumentIndex, routingKeyMethod);
			}
		}
		return result;
	}
	
	public static Router lookForRoutingAnnotationInMethodSignature(Method m) {
		Router routingStrategy = null;
		for (int argumentIndex = 0; argumentIndex < m.getParameterTypes().length; argumentIndex++) {
			for (Annotation a : m.getParameterAnnotations()[argumentIndex]) {
				if (a.annotationType().equals(Routing.class)) {
					if (routingStrategy != null) {
						throw new AmbiguousRoutingException(String.format("Ambiguous routing, multiple @Routing annotated methods on %s", m.toString()));
					}
					routingStrategy = createRoutingStrategy(m, argumentIndex, (Routing) a);
				}
			}
		}
		return routingStrategy;
	}

	public static Router createRoutingStrategy(Method serviceMethod, int routingArgumentIndex, Routing routingAnnotation) {
		if (routingAnnotation.value().trim().isEmpty()) {
			return new AnnotatedArgumentRouter(routingArgumentIndex);
		} 
		String targetRoutingMethod = routingAnnotation.value();
		try {
			Class type = serviceMethod.getParameterTypes()[routingArgumentIndex];
			Method method = type.getMethod(targetRoutingMethod);
			return new PropertyOnAnnotatedArgumentRoutingStrategy(routingArgumentIndex, method);
		} catch (NoSuchMethodException | SecurityException e) {
			throw new IllegalArgumentException("Cant route using: " + targetRoutingMethod , e);
		}
	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy