Capabilities expose core feign artifacts to implementations so parts of core can be customized around the time the client being built. For instance, capabilities take the Client, make changes to it and feed the modified version back to feign. @see Metrics5Capability
| 34 | * @see Metrics5Capability |
| 35 | */ |
| 36 | public interface Capability { |
| 37 | |
| 38 | static Object enrich( |
| 39 | Object componentToEnrich, Class<?> capabilityToEnrich, List<Capability> capabilities) { |
| 40 | return capabilities.stream() |
| 41 | // invoke each individual capability and feed the result to the next one. |
| 42 | // This is equivalent to: |
| 43 | // Capability cap1 = ...; |
| 44 | // Capability cap2 = ...; |
| 45 | // Capability cap2 = ...; |
| 46 | // Contract contract = ...; |
| 47 | // Contract contract1 = cap1.enrich(contract); |
| 48 | // Contract contract2 = cap2.enrich(contract1); |
| 49 | // Contract contract3 = cap3.enrich(contract2); |
| 50 | // or in a more compact version |
| 51 | // Contract enrichedContract = cap3.enrich(cap2.enrich(cap1.enrich(contract))); |
| 52 | .reduce( |
| 53 | componentToEnrich, |
| 54 | (target, capability) -> invoke(target, capability, capabilityToEnrich), |
| 55 | (component, enrichedComponent) -> enrichedComponent); |
| 56 | } |
| 57 | |
| 58 | static Object invoke(Object target, Capability capability, Class<?> capabilityToEnrich) { |
| 59 | return Arrays.stream(capability.getClass().getMethods()) |
| 60 | .filter(method -> method.getName().equals("enrich")) |
| 61 | .filter(method -> method.getReturnType().isAssignableFrom(capabilityToEnrich)) |
| 62 | .findFirst() |
| 63 | .map( |
| 64 | method -> { |
| 65 | try { |
| 66 | return method.invoke(capability, target); |
| 67 | } catch (IllegalAccessException |
| 68 | | IllegalArgumentException |
| 69 | | InvocationTargetException e) { |
| 70 | throw new RuntimeException("Unable to enrich " + target, e); |
| 71 | } |
| 72 | }) |
| 73 | .orElse(target); |
| 74 | } |
| 75 | |
| 76 | default Client enrich(Client client) { |
| 77 | return client; |
| 78 | } |
| 79 | |
| 80 | default AsyncClient<Object> enrich(AsyncClient<Object> client) { |
| 81 | return client; |
| 82 | } |
| 83 | |
| 84 | default Retryer enrich(Retryer retryer) { |
| 85 | return retryer; |
| 86 | } |
| 87 | |
| 88 | default RequestInterceptor enrich(RequestInterceptor requestInterceptor) { |
| 89 | return requestInterceptor; |
| 90 | } |
| 91 | |
| 92 | default ResponseInterceptor enrich(ResponseInterceptor responseInterceptor) { |
| 93 | return responseInterceptor; |
no outgoing calls
no test coverage detected