Skip to content

Package: ServiceInspector

ServiceInspector

nameinstructionbranchcomplexitylinemethod
getEventBusClients(KapuaService, Class)
M: 221 C: 0
0%
M: 30 C: 0
0%
M: 16 C: 0
0%
M: 42 C: 0
0%
M: 1 C: 0
0%
getMatchingMethod(Class, Method)
M: 69 C: 0
0%
M: 14 C: 0
0%
M: 8 C: 0
0%
M: 17 C: 0
0%
M: 1 C: 0
0%
lambda$getEventBusClients$0(Method, KapuaService, Method, ServiceEvent)
M: 25 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2017, 2022 Eurotech and/or its affiliates and others
3: *
4: * This program and the accompanying materials are made
5: * available under the terms of the Eclipse Public License 2.0
6: * which is available at https://www.eclipse.org/legal/epl-2.0/
7: *
8: * SPDX-License-Identifier: EPL-2.0
9: *
10: * Contributors:
11: * Eurotech - initial API and implementation
12: *******************************************************************************/
13: package org.eclipse.kapua.commons.event;
14:
15: import java.lang.reflect.InvocationTargetException;
16: import java.lang.reflect.Method;
17: import java.util.ArrayList;
18: import java.util.Arrays;
19: import java.util.List;
20:
21: import org.eclipse.kapua.KapuaException;
22: import org.eclipse.kapua.KapuaRuntimeException;
23: import org.eclipse.kapua.event.ListenServiceEvent;
24: import org.eclipse.kapua.event.RaiseServiceEvent;
25: import org.eclipse.kapua.event.ServiceEvent;
26: import org.eclipse.kapua.service.KapuaService;
27:
28: import org.apache.commons.lang3.ArrayUtils;
29: import org.slf4j.Logger;
30: import org.slf4j.LoggerFactory;
31:
32: public class ServiceInspector {
33:
34: private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInspector.class);
35:
36: private ServiceInspector() {}
37:
38: public static <T extends KapuaService> List<ServiceEventClientConfiguration> getEventBusClients(KapuaService aService, Class<T> clazz) {
39:
40: Class<? extends KapuaService> superclass = null;
41:• if (clazz.isAssignableFrom(aService.getClass().getSuperclass())) {
42: superclass = (Class<T>) aService.getClass().getSuperclass(); // Safe because of the check in the condition
43: }
44:
45: Method[] methods = aService.getClass().getMethods();
46: List<ServiceEventClientConfiguration> configurations = new ArrayList<>();
47:• for (Method method : methods) {
48: RaiseServiceEvent[] raiseAnnotations = method.getAnnotationsByType(RaiseServiceEvent.class);
49: ListenServiceEvent[] listenAnnotations = method.getAnnotationsByType(ListenServiceEvent.class);
50:• if (superclass != null && (ArrayUtils.isEmpty(listenAnnotations) || ArrayUtils.isEmpty(raiseAnnotations))) {
51: Method matchingMethod;
52: try {
53: matchingMethod = getMatchingMethod(superclass, method);
54:• if (ArrayUtils.isEmpty(listenAnnotations)) {
55: listenAnnotations = matchingMethod.getAnnotationsByType(ListenServiceEvent.class);
56: }
57:• if (ArrayUtils.isEmpty(raiseAnnotations)) {
58: raiseAnnotations = matchingMethod.getAnnotationsByType(RaiseServiceEvent.class);
59: }
60: } catch (NoSuchMethodException e) {
61: LOGGER.debug("Method not found in superclass: {}", method);
62: }
63: }
64:• if (!ArrayUtils.isEmpty(listenAnnotations) && !ArrayUtils.isEmpty(raiseAnnotations)) {
65: KapuaRuntimeException.internalError(String.format("A method cannot be annotated with both %s and %s", ListenServiceEvent.class, RaiseServiceEvent.class));
66: }
67:• if (!ArrayUtils.isEmpty(listenAnnotations)) {
68: Method enhancedMethod = null;
69: try {
70: enhancedMethod = aService.getClass().getMethod(method.getName(), method.getParameterTypes());
71:• if (!enhancedMethod.getReturnType().equals(Void.class)) {
72: KapuaRuntimeException.internalError("Invalid method signature: return type, expected Void");
73: }
74: int paramsSize = enhancedMethod.getParameterTypes().length;
75:• if (paramsSize != 1) {
76: KapuaRuntimeException.internalError(String.format("Invalid method signature: number of parameters %d, expected 1", paramsSize));
77: }
78: Class<?> paramClazz = enhancedMethod.getParameterTypes()[0];
79:• if (!enhancedMethod.getParameterTypes()[0].equals(ServiceEvent.class)) {
80: KapuaRuntimeException.internalError(String.format("Invalid method signature: type of parameters %s, expected ServiceEvent", paramClazz));
81: }
82: } catch (NoSuchMethodException | SecurityException e1) {
83: KapuaRuntimeException.internalError(e1, String.format("Unable to get the annotated method: annotation %s", ListenServiceEvent.class));
84: }
85:
86:• for (ListenServiceEvent listenAnnotation:listenAnnotations) {
87: final Method listenerMethod = enhancedMethod;
88: configurations.add(
89: new ServiceEventClientConfiguration(
90: listenAnnotation.fromAddress(),
91: clazz.getName(),
92: serviceEvent -> {
93: try {
94: listenerMethod.invoke(aService, serviceEvent);
95: } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
96: throw KapuaException.internalError(e, String.format("Error invoking method %s", method.getName()));
97: }
98: }));
99: }
100: }
101:• if (!ArrayUtils.isEmpty(raiseAnnotations)) {
102: configurations.add(
103: new ServiceEventClientConfiguration(
104: null,
105: clazz.getName(),
106: null));
107: }
108: }
109:
110: return configurations;
111: }
112:
113: private static Method getMatchingMethod(Class<?> clazz, Method method) throws NoSuchMethodException {
114: Method[] methods = clazz.getMethods();
115: Method matchingMethod = null;
116:
117:• if (methods.length > 0) {
118: List<Class<?>> methodParamTypes = Arrays.asList(method.getParameterTypes());
119:
120:• for (Method candidate : methods) {
121:• if (!candidate.getName().equals(method.getName())) {
122: continue;
123: }
124:• if (!candidate.getReturnType().equals(method.getReturnType())) {
125: continue;
126: }
127:
128: List<Class<?>> candidateParamTypes = Arrays.asList(method.getParameterTypes());
129:
130:• if (candidateParamTypes.size() != methodParamTypes.size() || !candidateParamTypes.containsAll(methodParamTypes)) {
131: continue;
132: }
133:
134: matchingMethod = candidate;
135: break;
136: }
137: }
138:• if (matchingMethod == null) {
139: throw new NoSuchMethodException(method.getName());
140: }
141: return matchingMethod;
142: }
143:
144: }