/** * Creates new {@link RxMethodDispatcher} if return type is in {@link RxMethodDispatcherProvider#allowedTypes}<br> * Original {@link ResourceMethodDispatcher} will be provided to created method dispatcher * * @param method the invocable resource method. * @param handler invocation handler to be used for the resource method invocation. * @param validator configured validator to be used for validation during resource method invocation * @return {@link RxMethodDispatcher}, or {@code null} if it could not be created for the given resource method. */ @Override public ResourceMethodDispatcher create(Invocable method, InvocationHandler handler, ConfiguredValidator validator) { final Class<?> returnType = method.getHandlingMethod().getReturnType(); if (!allowedTypes.contains(returnType)) { return null; } for (ResourceMethodDispatcher.Provider provider : providers) { ResourceMethodDispatcher dispatcher = provider.create(method, handler, validator); if (dispatcher != null) { dispatcher = create(dispatcher); serviceLocator.inject(dispatcher); return dispatcher; } } return null; }
private Router getMockRouter(String methodName, Class<?>... parameterTypes) throws NoSuchMethodException { Invocable mockInvocable = PowerMock.createMock(Invocable.class); expect(mockInvocable.getHandlingMethod()) .andReturn(DummyController.class.getDeclaredMethod(methodName, parameterTypes)) .anyTimes(); expect(mockInvocable.getHandler()) .andReturn(MethodHandler.create(DummyController.class)) .anyTimes(); org.lambadaframework.jaxrs.model.ResourceMethod mockResourceMethod = PowerMock.createMock(org.lambadaframework.jaxrs.model.ResourceMethod .class); expect(mockResourceMethod.getInvocable()) .andReturn(mockInvocable) .anyTimes(); Router mockRouter = PowerMock.createMock(Router.class); expect(mockRouter.route(anyObject())) .andReturn(mockResourceMethod) .anyTimes(); PowerMock.replayAll(); return mockRouter; }
@Override public ResourceMethodDispatcher create(Invocable method, InvocationHandler handler, ConfiguredValidator validator) { final Class<?> returnType = method.getHandlingMethod().getReturnType(); if(Publisher.class.isAssignableFrom(returnType) & !Collection.class.isAssignableFrom(returnType)){ Set<Provider> providers = serviceLocator.getAllServiceHandles(ResourceMethodDispatcher.Provider.class) .stream() .filter(h->!h.getActiveDescriptor() .getImplementationClass() .equals(AsyncDispatcherProvider.class)) .map(ServiceHandle::getService) .collect(Collectors.toSet()); for (ResourceMethodDispatcher.Provider provider : providers) { ResourceMethodDispatcher dispatcher = provider.create(method, handler, validator); if (dispatcher != null) { AsyncDispatcher result = new AsyncDispatcher(dispatcher); serviceLocator.inject(result); return result; } } } return null; }
/** * Builds the circuit breaker name with the given {@link ResourceMethod}. It * the method is {@code null} or the method is not annotated with * {@link CircuitBreaker} it will return {@code Optional.empty()}. * * @param resourceMethod * The method that may contain a {@link CircuitBreaker} * annotation and will be monitored. * @return An Optional of the circuit breaker name or * {@code Optional.empty()} if it's not annotated. */ private Optional<String> getCircuitBreakerName(final ResourceMethod resourceMethod) { // Apparently resourceMethod can be null. if (resourceMethod == null) { return Optional.empty(); } try (Timer.Context context = this.requestOverheadTimer.time()) { final Invocable invocable = resourceMethod.getInvocable(); Method method = invocable.getDefinitionMethod(); CircuitBreaker circuitBreaker = method.getAnnotation(CircuitBreaker.class); // In case it's a child class with a parent method annotated. if (circuitBreaker == null) { method = invocable.getHandlingMethod(); circuitBreaker = method.getAnnotation(CircuitBreaker.class); } if (circuitBreaker != null) { return Optional.of(StringUtils.defaultIfBlank(circuitBreaker.name(), name(invocable.getHandler().getHandlerClass(), method.getName()))); } else { return Optional.empty(); } } }
/** * Defines method for {@link Resource} to build * * @param builder * @param method * @param metaData */ private static void addMethod(Resource.Builder builder, ResourceMethod method, MetaData metaData) { List<MediaType> consumedTypes = method.getConsumedTypes(); List<MediaType> producedTypes = method.getProducedTypes(); Invocable invocable = method.getInvocable(); Method realMethod = invocable.getHandlingMethod(); List<Parameter> parameters = invocable.getParameters(); // Defines media type MediaType type; if (CollectionUtils.valid(consumedTypes)) { type = CollectionUtils.getFirst(consumedTypes); } else { type = null; } // REST Inflector to define bean methods Inflector<ContainerRequestContext, Response> inflector = new RestInflector( realMethod, metaData, type, parameters); // Builds new method for resource ResourceMethod.Builder methodBuilder = builder.addMethod(method .getHttpMethod()); methodBuilder.consumes(consumedTypes); methodBuilder.produces(producedTypes); methodBuilder.nameBindings(method.getNameBindings()); methodBuilder.handledBy(inflector); methodBuilder.build(); }
/** * Defines method for {@link Resource} to build * * @param builder * @param method * @param metaData */ private static void addMethod(Resource.Builder builder, ResourceMethod method, MetaData metaData) { List<MediaType> consumedTypes = method.getConsumedTypes(); List<MediaType> producedTypes = method.getProducedTypes(); Invocable invocable = method.getInvocable(); Method realMethod = invocable.getHandlingMethod(); List<Parameter> parameters = invocable.getParameters(); // Defines media type MediaType type; if (CollectionUtils.valid(consumedTypes)) { type = CollectionUtils.getFirst(consumedTypes); } else { type = null; } // Implementation of framework defined "Inflector" interface to define // bean // methods Inflector<ContainerRequestContext, Response> inflector = new RestInflector(realMethod, metaData, type, parameters); // Builds new method for resource ResourceMethod.Builder methodBuilder = builder.addMethod(method.getHttpMethod()); methodBuilder.consumes(consumedTypes); methodBuilder.produces(producedTypes); methodBuilder.nameBindings(method.getNameBindings()); methodBuilder.handledBy(inflector); methodBuilder.build(); }
@Override public InvocationHandler create(Invocable invocable) { return handlers.get(invocable.getRawResponseType()); }
public Invocable getInvocable() { return proxied.getInvocable(); }
@Override public InvocationHandler create(Invocable resourceMethod) { return new MyIncovationHandler(); }
@Override public InvocationHandler create(Invocable resourceMethod) { return new DirectMyIncovationHandler(); }
private void printResource(Resource resource) { StringBuilder sb = new StringBuilder(); List<ResourceMethod> resourceMethods = resource.getResourceMethods(); if (!resourceMethods.isEmpty()) { sb.append("Resource["); sb.append("\n\tpath="); Resource parent = resource.getParent(); while (parent != null) { sb.append(parent.getPath()); parent = parent.getParent(); } sb.append(resource.getPath()); // sb.append(",pattern=" + resource.getPathPattern()); // sb.append(",name=" + resource.getName()); sb.append(",\n\tmethods=["); for (ResourceMethod resourceMethod : resourceMethods) { sb.append("\n\t\t[" + resourceMethod.getHttpMethod()); sb.append(",producedTypes=" + resourceMethod.getProducedTypes()); sb.append(",nameBindings=" + resourceMethod.getNameBindings()); Invocable invocable = resourceMethod.getInvocable(); sb.append(",handlingMethod=" + invocable.getHandlingMethod().getName()); if (invocable.getResponseType() != null) { sb.append(",responseType=" + invocable.getResponseType()); } else { sb.append(",rawResponseType=" + invocable.getRawResponseType()); } sb.append(",parameters["); for (Parameter parameter : invocable.getParameters()) { sb.append("[rawType=" + parameter.getRawType()); sb.append(",type=" + parameter.getType() + "]"); } sb.append("]"); sb.append("]"); } sb.append("\n\t]"); System.out.println(sb.toString()); } if (!resource.getChildResources().isEmpty()) { for (Resource childResource : resource.getChildResources()) { printResource(childResource); } } }