ref #8812 option for measuring remoting method execution duration
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Mon, 17 Feb 2020 13:07:37 +0000 (14:07 +0100)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Mon, 17 Feb 2020 13:07:46 +0000 (14:07 +0100)
cdmlib-remote-webapp/ide/eclipse/Jetty Launcher/cdmlib-remote-webapp - run.launch
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/remoting/DebuggingRemoteInvocationExecutor.java [new file with mode: 0644]
cdmlib-services/src/main/resources/eu/etaxonomy/cdm/httpInvokerServices.xml

index 686419049b740f71686d86b74899cd6466ac0165..1033d89931c9bd3b4a9cb6a3905e1d0f1c474ff6 100755 (executable)
@@ -56,5 +56,5 @@
 <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="net.sourceforge.eclipsejetty.launcher.JettyLaunchClassPathProvider"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.sourceforge.eclipsejetty.starter.jetty9.Jetty9LauncherMain"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="cdmlib-remote-webapp"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2000M&#13;&#10;&#13;&#10;-Dlog4j.configDebug=false&#13;&#10;-Dlog4j.configuration=file:///${system_property:user.home}/.cdmLibrary/log4j.properties&#13;&#10;&#13;&#10;-Dcdm.forceSchemaUpdate=true&#13;&#10;-Dspring.profiles.active=remoting"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2000M&#13;&#10;&#13;&#10;-Dlog4j.configDebug=false&#13;&#10;-Dlog4j.configuration=file:///${system_property:user.home}/.cdmLibrary/log4j.properties&#13;&#10;&#13;&#10;-Dcdm.forceSchemaUpdate=true&#13;&#10;-Dspring.profiles.active=remoting&#10;-Dremoting.measureDuration"/>
 </launchConfiguration>
diff --git a/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/remoting/DebuggingRemoteInvocationExecutor.java b/cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/remoting/DebuggingRemoteInvocationExecutor.java
new file mode 100644 (file)
index 0000000..78b3e0d
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+* 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;
+    }
+
+
+
+
+}
index 5bb85fcdba2a20a2bb9f6f68115dbf0514c335c0..9d054e6f4d34316a3a6c667932ba461aa35d3ce5 100644 (file)
@@ -11,6 +11,9 @@
   <!-- 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
@@ -19,6 +22,7 @@
     <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
@@ -29,6 +33,7 @@
     <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
@@ -39,6 +44,7 @@
     <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
@@ -49,6 +55,7 @@
     <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
@@ -59,6 +66,7 @@
     <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
@@ -80,6 +89,7 @@
     <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