--- /dev/null
+/**
+* Copyright (C) 2020 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.api.remoting;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+import org.apache.log4j.Logger;
+import org.springframework.remoting.support.RemoteInvocation;
+import org.springframework.remoting.support.RemoteInvocationExecutor;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Alternative implementation of the {@link RemoteInvocationExecutor} interface which behaves exactly
+ * as the {@link org.springframework.remoting.support.DefaultRemoteInvocationExecutor} with the
+ * additional capability of measuring the execution of the method invocation.
+ * <p>
+ * The execution duration in milliseconds will be written to the log when the log level for this
+ * class is set to <code>DEBUG</code>.
+ *
+ * @author a.kohlbecker
+ * @since Feb 17, 2020
+ *
+ */
+public class DebuggingRemoteInvocationExecutor implements RemoteInvocationExecutor {
+
+ private static final Logger logger = Logger.getLogger(DebuggingRemoteInvocationExecutor.class);
+
+ @Override
+ public Object invoke(RemoteInvocation invocation, Object targetObject)
+ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{
+
+ Assert.notNull(invocation, "RemoteInvocation must not be null");
+ Assert.notNull(targetObject, "Target object must not be null");
+ boolean domeasure = logger.isDebugEnabled();
+ String targetInvocationStr = null;
+ long start = 0;
+ if(domeasure) {
+ targetInvocationStr = targetCdmServiceInterfaces(targetObject) + "#" + invocation.getMethodName() + "(" +
+ ClassUtils.classNamesToString(invocation.getParameterTypes()) + ")";
+ logger.debug("invoking: " + targetInvocationStr);
+ start = System.currentTimeMillis();
+ }
+ Object invocationResult = invocation.invoke(targetObject);
+ if (domeasure) {
+ logger.debug("invocation: " + targetInvocationStr + " completed [" + (System.currentTimeMillis() - start) + " ms]");
+ }
+
+ return invocationResult;
+ }
+
+ /**
+ * @param targetObject
+ * @return
+ */
+ private String targetCdmServiceInterfaces(Object targetObject) {
+ String interfacesStr = targetObject.getClass().getName();
+ if(interfacesStr.contains("$Proxy")){
+ Class<?>[] intfs = targetObject.getClass().getInterfaces();
+ interfacesStr = Arrays.stream(intfs).map(c -> c.getName())
+ .filter(n -> n.startsWith("eu.etaxonomy.cdm.api.service."))
+ .collect( Collectors.joining( "," ) );
+ }
+ return interfacesStr;
+ }
+
+
+
+
+}
<!-- The beans for the implementation classes are declared with the @Service \r
annotation. See ClassificationServiceImpl for an example. -->\r
\r
+ <bean id="remoteInvocationExecutor" class="eu.etaxonomy.cdm.api.remoting.DebuggingRemoteInvocationExecutor"\r
+ scope="prototype" />\r
+\r
<bean id="httpAgentService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IAgentService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpAnnotationService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IAnnotationService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpAuditEventService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IAuditEventService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpClassificationService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IClassificationService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpCollectionService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ICollectionService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpCommonService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ICommonService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
- \r
+\r
+\r
<bean id="httpDescriptionService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IDescriptionService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpFeatureNodeService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IFeatureNodeService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpTermNodeService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ITermNodeService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpFeatureTreeService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IFeatureTreeService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpTermTreeService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ITermTreeService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpGroupService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IGroupService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpIdentificationKeyService"\r
<value>eu.etaxonomy.cdm.api.service.IIdentificationKeyService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpLocationService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ILocationService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpMarkerService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IMarkerService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpMediaService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IMediaService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
- <bean id="httpMetadataService"\r
+\r
+ <bean id="httpMetadataService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<ref bean="metadataServiceImpl" />\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IMetadataService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpNameService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.INameService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpOccurrenceService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IOccurrenceService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpPolytomousKeyNodeService"\r
<value>eu.etaxonomy.cdm.api.service.IPolytomousKeyNodeService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpPolytomousKeyService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IPolytomousKeyService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpPreferenceService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IPreferenceService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpProgressMonitorService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<ref bean="progressMonitorServiceImpl" />\r
</property>\r
<property name="serviceInterface">\r
- <value>eu.etaxonomy.cdm.api.service.IProgressMonitorService</value>\r
+ <value>eu.etaxonomy.cdm.api.service.IProgressMonitorService\r
+ </value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpReferenceService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IReferenceService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
- <bean id="httpExtReferenceService"\r
+\r
+ <bean id="httpExtReferenceService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<ref bean="referenceServiceImpl" />\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IReferenceService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpBaseService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpTaxonNodeService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ITaxonNodeService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpTaxonService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ITaxonService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpTermService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.ITermService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
- <bean id="httpRightsService"\r
+\r
+ <bean id="httpRightsService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<ref bean="rightsServiceImpl" />\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IRightsService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpEntityValidationService"\r
<value>eu.etaxonomy.cdm.api.service.IEntityValidationService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpEntityConstraintViolationService"\r
<value>eu.etaxonomy.cdm.api.service.IEntityConstraintViolationService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpUserService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IUserService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpVocabularyService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IVocabularyService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpDescriptiveDataSetService"\r
<ref bean="descriptiveDataSetService" />\r
</property>\r
<property name="serviceInterface">\r
- <value>eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService</value>\r
+ <value>eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService\r
+ </value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpGrantedAuthorityService"\r
<value>eu.etaxonomy.cdm.api.service.IGrantedAuthorityService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpDatabaseService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.IDatabaseService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpLsidAuthorityService"\r
<value>eu.etaxonomy.cdm.api.service.lsid.LSIDAuthorityService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpLsidMetadataService"\r
<value>eu.etaxonomy.cdm.api.service.lsid.LSIDMetadataService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpLsidDataService"\r
<property name="serviceInterface">\r
<value>eu.etaxonomy.cdm.api.service.lsid.LSIDDataService</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpAuthenticationManager"\r
<value>org.springframework.security.authentication.AuthenticationManager\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpPrimerService"\r
<value>eu.etaxonomy.cdm.api.service.molecular.IPrimerService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpAmplificationService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<value>eu.etaxonomy.cdm.api.service.molecular.IAmplificationService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpSequenceService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<value>eu.etaxonomy.cdm.api.service.molecular.ISequenceService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
\r
<bean id="httpEventBaseService"\r
<value>eu.etaxonomy.cdm.api.service.IEventBaseService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpIOService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<value>eu.etaxonomy.cdm.io.service.IIOService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
+\r
<bean id="httpLongRunningTasksService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<value>eu.etaxonomy.cdm.api.service.longrunningService.ILongRunningTasksService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
- \r
- <bean id="httpTestService"\r
+\r
+ <bean id="httpTestService"\r
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">\r
<property name="service">\r
<ref bean="testServiceImpl" />\r
<value>eu.etaxonomy.cdm.api.service.ITestService\r
</value>\r
</property>\r
+ <property name="remoteInvocationExecutor" ref="remoteInvocationExecutor" />\r
</bean>\r
-</beans>
\ No newline at end of file
+</beans>\r