private MetaHolder createCopy(MetaHolder source, ExecutionType executionType) { return MetaHolder.builder() .obj(source.getObj()) .method(source.getMethod()) .ajcMethod(source.getAjcMethod()) .fallbackExecutionType(source.getFallbackExecutionType()) .extendedFallback(source.isExtendedFallback()) .extendedParentFallback(source.isExtendedParentFallback()) .executionType(executionType) .args(source.getArgs()) .observable(source.isObservable()) .observableExecutionMode(source.getObservableExecutionMode()) .defaultCollapserKey(source.getDefaultCollapserKey()) .defaultCommandKey(source.getDefaultCommandKey()) .defaultGroupKey(source.getDefaultGroupKey()) .defaultThreadPoolKey(source.getDefaultThreadPoolKey()) .defaultProperties(source.getDefaultProperties().orNull()) .hystrixCollapser(source.getHystrixCollapser()) .hystrixCommand(source.getHystrixCommand()).build(); }
public MetaHolder build() { return new MetaHolder(this); }
public String getCommandGroupKey() { return isCommandAnnotationPresent() ? get(hystrixCommand.groupKey(), defaultGroupKey) : ""; }
public String getCollapserKey() { return isCollapserAnnotationPresent() ? get(hystrixCollapser.collapserKey(), defaultCollapserKey) : ""; }
FallbackMethod fallbackMethod = MethodProvider.getInstance().getFallbackMethod(metaHolder.getObj().getClass(), metaHolder.getMethod(), metaHolder.isExtendedFallback()); fallbackMethod.validateReturnType(metaHolder.getMethod()); CommandAction fallbackAction = null; if (fallbackMethod.isPresent()) { Object[] args = fallbackMethod.isDefault() ? new Object[0] : metaHolder.getArgs(); if (fallbackMethod.isCommand()) { fMethod.setAccessible(true); HystrixCommand hystrixCommand = fMethod.getAnnotation(HystrixCommand.class); MetaHolder fmMetaHolder = MetaHolder.builder() .obj(metaHolder.getObj()) .method(fMethod) .ajcMethod(getAjcMethod(metaHolder.getObj(), fMethod)) .args(args) .fallback(true) .defaultFallback(fallbackMethod.isDefault()) .defaultCollapserKey(metaHolder.getDefaultCollapserKey()) .fallbackMethod(fMethod) .extendedFallback(fallbackMethod.isExtended()) .fallbackExecutionType(fallbackMethod.getExecutionType()) .extendedParentFallback(metaHolder.isExtendedFallback()) .observable(ExecutionType.OBSERVABLE == fallbackMethod.getExecutionType()) .defaultCommandKey(fMethod.getName()) .defaultGroupKey(metaHolder.getDefaultGroupKey()) .defaultThreadPoolKey(metaHolder.getDefaultThreadPoolKey()) .defaultProperties(metaHolder.getDefaultProperties().orNull()) .hystrixCollapser(metaHolder.getHystrixCollapser()) .observableExecutionMode(hystrixCommand.observableExecutionMode())
private GenericSetterBuilder createGenericSetterBuilder(MetaHolder metaHolder) { GenericSetterBuilder.Builder setterBuilder = GenericSetterBuilder.builder() .groupKey(metaHolder.getCommandGroupKey()) .threadPoolKey(metaHolder.getThreadPoolKey()) .commandKey(metaHolder.getCommandKey()) .collapserKey(metaHolder.getCollapserKey()) .commandProperties(metaHolder.getCommandProperties()) .threadPoolProperties(metaHolder.getThreadPoolProperties()) .collapserProperties(metaHolder.getCollapserProperties()); if (metaHolder.isCollapserAnnotationPresent()) { setterBuilder.scope(metaHolder.getHystrixCollapser().scope()); } return setterBuilder.build(); }
private static MethodExecutionAction createCacheKeyAction(String method, MetaHolder metaHolder) { MethodExecutionAction cacheKeyAction = null; if (StringUtils.isNotBlank(method)) { Method cacheKeyMethod = getDeclaredMethod(metaHolder.getObj().getClass(), method, metaHolder.getMethod().getParameterTypes()); if (cacheKeyMethod == null) { throw new HystrixCachingException("method with name '" + method + "' doesn't exist in class '" + metaHolder.getObj().getClass() + "'"); } if (!cacheKeyMethod.getReturnType().equals(String.class)) { throw new HystrixCachingException("return type of cacheKey method must be String. Method: '" + method + "', Class: '" + metaHolder.getObj().getClass() + "'"); } MetaHolder cMetaHolder = MetaHolder.builder().obj(metaHolder.getObj()).method(cacheKeyMethod).args(metaHolder.getArgs()).build(); cacheKeyAction = new MethodExecutionAction(cMetaHolder.getObj(), cacheKeyMethod, cMetaHolder.getArgs(), cMetaHolder); } return cacheKeyAction; }
@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()") public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable { Method method = getMethodFromTarget(joinPoint); Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint); if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) { throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " + "annotations at the same time"); } MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method)); MetaHolder metaHolder = metaHolderFactory.create(joinPoint); HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder); ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ? metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType(); Object result; try { if (!metaHolder.isObservable()) { result = CommandExecutor.execute(invokable, executionType, metaHolder); } else { result = executeObservable(invokable, executionType, metaHolder); } } catch (HystrixBadRequestException e) { throw e.getCause() != null ? e.getCause() : e; } catch (HystrixRuntimeException e) { throw hystrixRuntimeExceptionToThrowable(metaHolder, e); } return result; }
MetaHolder.Builder metaHolderBuilder(Object proxy, Method method, Object obj, Object[] args, final ProceedingJoinPoint joinPoint) { MetaHolder.Builder builder = MetaHolder.builder() .args(args).method(method).obj(obj).proxyObj(proxy) .joinPoint(joinPoint); setFallbackMethod(builder, obj.getClass(), method); builder = setDefaultProperties(builder, obj.getClass(), joinPoint); return builder; } }
public <ResponseType> HystrixCommandBuilder create(MetaHolder metaHolder, Collection<HystrixCollapser.CollapsedRequest<ResponseType, Object>> collapsedRequests) { validateMetaHolder(metaHolder); return HystrixCommandBuilder.builder() .setterBuilder(createGenericSetterBuilder(metaHolder)) .commandActions(createCommandActions(metaHolder)) .collapsedRequests(collapsedRequests) .cacheResultInvocationContext(createCacheResultInvocationContext(metaHolder)) .cacheRemoveInvocationContext(createCacheRemoveInvocationContext(metaHolder)) .ignoreExceptions(metaHolder.getCommandIgnoreExceptions()) .executionType(metaHolder.getExecutionType()) .build(); }
/** * {@inheritDoc} */ @Override public Object getRequestArgument() { return metaHolder.getArgs(); }
@Override public Closure createClosure(MetaHolder metaHolder, Method method, Object o, Object... args) { try { Object closureObj; method.setAccessible(true); if (isCompileWeaving()) { closureObj = invokeAjcMethod(metaHolder.getAjcMethod(), o, metaHolder, args); } else { closureObj = method.invoke(o, args); // creates instance of an anonymous class } return createClosure(method.getName(), closureObj); } catch (InvocationTargetException e) { throw Throwables.propagate(e.getCause()); } catch (Exception e) { throw Throwables.propagate(e); } }
FallbackMethod fallbackMethod = MethodProvider.getInstance().getFallbackMethod(metaHolder.getObj().getClass(), metaHolder.getMethod(), metaHolder.isExtendedFallback()); fallbackMethod.validateReturnType(metaHolder.getMethod()); CommandAction fallbackAction = null; if (fallbackMethod.isPresent()) { Object[] args = fallbackMethod.isDefault() ? new Object[0] : metaHolder.getArgs(); if (fallbackMethod.isCommand()) { fMethod.setAccessible(true); HystrixCommand hystrixCommand = fMethod.getAnnotation(HystrixCommand.class); MetaHolder fmMetaHolder = MetaHolder.builder() .obj(metaHolder.getObj()) .method(fMethod) .ajcMethod(getAjcMethod(metaHolder.getObj(), fMethod)) .args(args) .fallback(true) .defaultFallback(fallbackMethod.isDefault()) .defaultCollapserKey(metaHolder.getDefaultCollapserKey()) .fallbackMethod(fMethod) .extendedFallback(fallbackMethod.isExtended()) .fallbackExecutionType(fallbackMethod.getExecutionType()) .extendedParentFallback(metaHolder.isExtendedFallback()) .observable(ExecutionType.OBSERVABLE == fallbackMethod.getExecutionType()) .defaultCommandKey(fMethod.getName()) .defaultGroupKey(metaHolder.getDefaultGroupKey()) .defaultThreadPoolKey(metaHolder.getDefaultThreadPoolKey()) .defaultProperties(metaHolder.getDefaultProperties().orNull()) .hystrixCollapser(metaHolder.getHystrixCollapser()) .observableExecutionMode(hystrixCommand.observableExecutionMode())
private GenericSetterBuilder createGenericSetterBuilder(MetaHolder metaHolder) { GenericSetterBuilder.Builder setterBuilder = GenericSetterBuilder.builder() .groupKey(metaHolder.getCommandGroupKey()) .threadPoolKey(metaHolder.getThreadPoolKey()) .commandKey(metaHolder.getCommandKey()) .collapserKey(metaHolder.getCollapserKey()) .commandProperties(metaHolder.getCommandProperties()) .threadPoolProperties(metaHolder.getThreadPoolProperties()) .collapserProperties(metaHolder.getCollapserProperties()); if (metaHolder.isCollapserAnnotationPresent()) { setterBuilder.scope(metaHolder.getHystrixCollapser().scope()); } return setterBuilder.build(); }
/** * Create {@link CacheInvocationContext} parametrized with {@link CacheResult} annotation. * * @param metaHolder the meta holder, see {@link com.netflix.hystrix.contrib.javanica.command.MetaHolder} * @return initialized and configured {@link CacheInvocationContext} */ public static CacheInvocationContext<CacheResult> createCacheResultInvocationContext(MetaHolder metaHolder) { Method method = metaHolder.getMethod(); if (method.isAnnotationPresent(CacheResult.class)) { CacheResult cacheResult = method.getAnnotation(CacheResult.class); MethodExecutionAction cacheKeyMethod = createCacheKeyAction(cacheResult.cacheKeyMethod(), metaHolder); return new CacheInvocationContext<CacheResult>(cacheResult, cacheKeyMethod, metaHolder.getObj(), method, metaHolder.getArgs()); } return null; }
private static MethodExecutionAction createCacheKeyAction(String method, MetaHolder metaHolder) { MethodExecutionAction cacheKeyAction = null; if (StringUtils.isNotBlank(method)) { Method cacheKeyMethod = getDeclaredMethod(metaHolder.getObj().getClass(), method, metaHolder.getMethod().getParameterTypes()); if (cacheKeyMethod == null) { throw new HystrixCachingException("method with name '" + method + "' doesn't exist in class '" + metaHolder.getObj().getClass() + "'"); } if (!cacheKeyMethod.getReturnType().equals(String.class)) { throw new HystrixCachingException("return type of cacheKey method must be String. Method: '" + method + "', Class: '" + metaHolder.getObj().getClass() + "'"); } MetaHolder cMetaHolder = MetaHolder.builder().obj(metaHolder.getObj()).method(cacheKeyMethod).args(metaHolder.getArgs()).build(); cacheKeyAction = new MethodExecutionAction(cMetaHolder.getObj(), cacheKeyMethod, cMetaHolder.getArgs(), cMetaHolder); } return cacheKeyAction; }
@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()") public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable { Method method = getMethodFromTarget(joinPoint); Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint); if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) { throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " + "annotations at the same time"); } MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method)); MetaHolder metaHolder = metaHolderFactory.create(joinPoint); HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder); ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ? metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType(); Object result; try { if (!metaHolder.isObservable()) { result = CommandExecutor.execute(invokable, executionType, metaHolder); } else { result = executeObservable(invokable, executionType, metaHolder); } } catch (HystrixBadRequestException e) { throw e.getCause(); } catch (HystrixRuntimeException e) { throw hystrixRuntimeExceptionToThrowable(metaHolder, e); } return result; }
@Around("cacheRemoveAnnotationPointcut()") public Object methodsAnnotatedWithCacheRemove(final ProceedingJoinPoint joinPoint) throws Throwable { Method method = getMethodFromTarget(joinPoint); Object obj = joinPoint.getTarget(); Object[] args = joinPoint.getArgs(); Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint); MetaHolder metaHolder = MetaHolder.builder() .args(args).method(method).obj(obj) .executionType(ExecutionType.SYNCHRONOUS) .ajcMethod(isCompileWeaving() ? getAjcMethodAroundAdvice(obj.getClass(), method) : null) .build(); CacheInvocationContext<CacheRemove> context = CacheInvocationContextFactory .createCacheRemoveInvocationContext(metaHolder); HystrixRequestCacheManager.getInstance().clearCache(context); return joinPoint.proceed(); }
public <ResponseType> HystrixCommandBuilder create(MetaHolder metaHolder, Collection<HystrixCollapser.CollapsedRequest<ResponseType, Object>> collapsedRequests) { validateMetaHolder(metaHolder); return HystrixCommandBuilder.builder() .setterBuilder(createGenericSetterBuilder(metaHolder)) .commandActions(createCommandActions(metaHolder)) .collapsedRequests(collapsedRequests) .cacheResultInvocationContext(createCacheResultInvocationContext(metaHolder)) .cacheRemoveInvocationContext(createCacheRemoveInvocationContext(metaHolder)) .ignoreExceptions(metaHolder.getCommandIgnoreExceptions()) .executionType(metaHolder.getExecutionType()) .build(); }