You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by rm...@apache.org on 2016/10/20 07:18:43 UTC

svn commit: r1765758 - in /openwebbeans/microwave/trunk/microwave-core/src/main: java/org/apache/catalina/ java/org/apache/catalina/startup/ java/org/apache/microwave/ java/org/apache/microwave/cxf/ resources/

Author: rmannibucau
Date: Thu Oct 20 07:18:43 2016
New Revision: 1765758

URL: http://svn.apache.org/viewvc?rev=1765758&view=rev
Log:
probably better logging pattern as default + skipping tomcat scanning by default (skip servlet)

Added:
    openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/
    openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/startup/
    openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/startup/MicrowaveContextConfig.java
Modified:
    openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java
    openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java
    openwebbeans/microwave/trunk/microwave-core/src/main/resources/log4j2.xml

Added: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/startup/MicrowaveContextConfig.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/startup/MicrowaveContextConfig.java?rev=1765758&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/startup/MicrowaveContextConfig.java (added)
+++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/catalina/startup/MicrowaveContextConfig.java Thu Oct 20 07:18:43 2016
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.catalina.startup;
+
+import org.apache.microwave.Microwave;
+import org.apache.tomcat.util.descriptor.web.WebXml;
+
+import java.net.URL;
+import java.util.Map;
+
+public class MicrowaveContextConfig extends ContextConfig {
+    private final Microwave.Builder configuration;
+
+    public MicrowaveContextConfig(final Microwave.Builder configuration) {
+        this.configuration = configuration;
+    }
+
+    @Override
+    protected void processAnnotationsUrl(final URL url, final WebXml fragment, final boolean handlesTypesOnly,
+                                         final Map<String, JavaClassCacheEntry> javaClassCache) {
+        if (configuration.isTomcatScanning()) {
+            super.processAnnotationsUrl(url, fragment, handlesTypesOnly, javaClassCache);
+        }
+    }
+}

Modified: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java?rev=1765758&r1=1765757&r2=1765758&view=diff
==============================================================================
--- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java (original)
+++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/Microwave.java Thu Oct 20 07:18:43 2016
@@ -34,7 +34,7 @@ import org.apache.catalina.core.Standard
 import org.apache.catalina.session.ManagerBase;
 import org.apache.catalina.session.StandardManager;
 import org.apache.catalina.startup.Catalina;
-import org.apache.catalina.startup.ContextConfig;
+import org.apache.catalina.startup.MicrowaveContextConfig;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.text.StrLookup;
@@ -45,6 +45,7 @@ import org.apache.microwave.cxf.CxfCdiAu
 import org.apache.microwave.logging.jul.Log4j2Logger;
 import org.apache.microwave.logging.openwebbeans.Log4j2LoggerFactory;
 import org.apache.microwave.logging.tomcat.Log4j2Log;
+import org.apache.microwave.logging.tomcat.LogFacade;
 import org.apache.microwave.openwebbeans.OWBAutoSetup;
 import org.apache.microwave.runner.cli.CliOption;
 import org.apache.microwave.tomcat.ProvidedLoader;
@@ -134,6 +135,10 @@ public class Microwave implements AutoCl
         if (contexts.containsKey(context)) {
             throw new IllegalArgumentException("Already deployed: '" + context + "'");
         }
+        // always nice to see the deployment with something else than internals
+        new LogFacade(Microwave.class.getName())
+                .info("--------------- " + configuration.getActiveProtocol() + "://"
+                        + tomcat.getHost().getName() + ':' + configuration.getActivePort() + context);
 
         final StandardContext ctx = new StandardContext();
         ctx.setPath(context);
@@ -144,7 +149,7 @@ public class Microwave implements AutoCl
             ctx.setDocBase(warOrDir.getAbsolutePath());
         }
         ctx.addLifecycleListener(new Tomcat.FixContextListener());
-        ctx.addLifecycleListener(new ContextConfig());
+        ctx.addLifecycleListener(new MicrowaveContextConfig(configuration));
         ctx.addLifecycleListener(event -> {
             switch (event.getType()) {
                 case Lifecycle.AFTER_START_EVENT:
@@ -654,10 +659,32 @@ public class Microwave implements AutoCl
         @CliOption(name = "logging-global-setup", description = "Should logging be configured to use log4j2 (it is global)")
         private boolean loggingGlobalSetup = true;
 
+        @CliOption(name = "cxf-servlet-params", description = "Init parameters passed to CXF servlet")
+        private Map<String, String> cxfServletParams;
+
+        @CliOption(name = "tomcat-scanning", description = "Should Tomcat scanning be used (@HandleTypes, @WebXXX)")
+        private boolean tomcatScanning = false;
+
         public Builder() { // load defaults
             loadFrom("microwave.properties");
         }
 
+        public boolean isTomcatScanning() {
+            return tomcatScanning;
+        }
+
+        public void setTomcatScanning(final boolean tomcatScanning) {
+            this.tomcatScanning = tomcatScanning;
+        }
+
+        public Map<String, String> getCxfServletParams() {
+            return cxfServletParams;
+        }
+
+        public void setCxfServletParams(final Map<String, String> cxfServletParams) {
+            this.cxfServletParams = cxfServletParams;
+        }
+
         public boolean isLoggingGlobalSetup() {
             return loggingGlobalSetup;
         }
@@ -984,6 +1011,14 @@ public class Microwave implements AutoCl
             return this;
         }
 
+        public Builder cxfServletParam(final String key, final String value) {
+            if (this.cxfServletParams == null) {
+                this.cxfServletParams = new HashMap<>();
+            }
+            this.cxfServletParams.put(key, value);
+            return this;
+        }
+
         public void addCustomizer(final ConfigurationCustomizer configurationCustomizer) {
             configurationCustomizer.customize(this);
         }
@@ -1097,6 +1132,26 @@ public class Microwave implements AutoCl
             if (conf != null) {
                 this.conf = conf;
             }
+            final String jaxrsMapping = config.getProperty("jaxrsMapping");
+            if (jaxrsMapping != null) {
+                this.jaxrsMapping = jaxrsMapping;
+            }
+            final String cdiConversation = config.getProperty("cdiConversation");
+            if (cdiConversation != null) {
+                this.cdiConversation = Boolean.parseBoolean(cdiConversation);
+            }
+            final String jaxrsProviderSetup = config.getProperty("jaxrsProviderSetup");
+            if (jaxrsProviderSetup != null) {
+                this.jaxrsProviderSetup = Boolean.parseBoolean(jaxrsProviderSetup);
+            }
+            final String loggingGlobalSetup = config.getProperty("loggingGlobalSetup");
+            if (loggingGlobalSetup != null) {
+                this.loggingGlobalSetup = Boolean.parseBoolean(loggingGlobalSetup);
+            }
+            final String tomcatScanning = config.getProperty("tomcatScanning");
+            if (tomcatScanning != null) {
+                this.tomcatScanning = Boolean.parseBoolean(tomcatScanning);
+            }
             for (final String prop : config.stringPropertyNames()) {
                 if (prop.startsWith("properties.")) {
                     property(prop.substring("properties.".length()), config.getProperty(prop));
@@ -1104,6 +1159,8 @@ public class Microwave implements AutoCl
                     user(prop.substring("users.".length()), config.getProperty(prop));
                 } else if (prop.startsWith("roles.")) {
                     role(prop.substring("roles.".length()), config.getProperty(prop));
+                } else if (prop.startsWith("cxf.servlet.params.")) {
+                    cxfServletParam(prop.substring("cxf.servlet.params.".length()), config.getProperty(prop));
                 } else if (prop.startsWith("connector.")) { // created in container
                     property(prop, config.getProperty(prop));
                 } else if (prop.equals("realm")) {
@@ -1145,6 +1202,14 @@ public class Microwave implements AutoCl
                 }
             }
         }
+
+        public String getActiveProtocol() {
+            return isSkipHttp() ? "https" : "http";
+        }
+
+        public int getActivePort() {
+            return isSkipHttp() ? getHttpsPort() : getHttpPort();
+        }
     }
 
     public static class LoginConfigBuilder {

Modified: openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java?rev=1765758&r1=1765757&r2=1765758&view=diff
==============================================================================
--- openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java (original)
+++ openwebbeans/microwave/trunk/microwave-core/src/main/java/org/apache/microwave/cxf/CxfCdiAutoSetup.java Thu Oct 20 07:18:43 2016
@@ -19,22 +19,38 @@
 package org.apache.microwave.cxf;
 
 import org.apache.cxf.cdi.CXFCdiServlet;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.MethodDispatcher;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
 import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
 import org.apache.cxf.transport.ChainInitiationObserver;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.servlet.ServletDestination;
 import org.apache.johnzon.jaxrs.DelegateProvider;
 import org.apache.johnzon.jaxrs.JohnzonProvider;
 import org.apache.johnzon.jaxrs.JsrProvider;
 import org.apache.microwave.Microwave;
+import org.apache.microwave.logging.tomcat.LogFacade;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRegistration;
+import javax.ws.rs.core.Application;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
 import static java.util.Arrays.asList;
+import static java.util.Optional.ofNullable;
 
 public class CxfCdiAutoSetup implements ServletContainerInitializer {
     @Override
@@ -64,9 +80,256 @@ public class CxfCdiAutoSetup implements
                             providerFactory.setUserProviders(providers);
                         });
             }
+
+            @Override
+            public void init(final ServletConfig sc) throws ServletException {
+                super.init(sc);
+
+                // just logging the endpoints
+                final LogFacade log = new LogFacade(CxfCdiAutoSetup.class.getName());
+                final DestinationRegistry registry = getDestinationRegistryFromBus();
+                registry.getDestinations().stream()
+                        .filter(ServletDestination.class::isInstance)
+                        .map(ServletDestination.class::cast)
+                        .forEach(sd -> {
+                            final Endpoint endpoint = ChainInitiationObserver.class.cast(sd.getMessageObserver()).getEndpoint();
+                            final ApplicationInfo app = ApplicationInfo.class.cast(endpoint.get(Application.class.getName()));
+                            final JAXRSServiceFactoryBean sfb = JAXRSServiceFactoryBean.class.cast(endpoint.get(JAXRSServiceFactoryBean.class.getName()));
+
+                            final List<Logs.LogResourceEndpointInfo> resourcesToLog = new ArrayList<>();
+                            int classSize = 0;
+                            int addressSize = 0;
+
+                            final String base = sd.getEndpointInfo().getAddress();
+                            final List<ClassResourceInfo> resources = sfb.getClassResourceInfo();
+                            for (final ClassResourceInfo info : resources) {
+                                if (info.getResourceClass() == null) { // possible?
+                                    continue;
+                                }
+
+                                final String address = Logs.singleSlash(base, info.getURITemplate().getValue());
+
+                                final String clazz = info.getResourceClass().getName();
+                                classSize = Math.max(classSize, clazz.length());
+                                addressSize = Math.max(addressSize, address.length());
+
+                                int methodSize = 7;
+                                int methodStrSize = 0;
+
+                                final List<Logs.LogOperationEndpointInfo> toLog = new ArrayList<>();
+
+                                final MethodDispatcher md = info.getMethodDispatcher();
+                                for (final OperationResourceInfo ori : md.getOperationResourceInfos()) {
+                                    final String httpMethod = ori.getHttpMethod();
+                                    final String currentAddress = Logs.singleSlash(address, ori.getURITemplate().getValue());
+                                    final String methodToStr = Logs.toSimpleString(ori.getMethodToInvoke());
+                                    toLog.add(new Logs.LogOperationEndpointInfo(httpMethod, currentAddress, methodToStr));
+
+                                    if (httpMethod != null) {
+                                        methodSize = Math.max(methodSize, httpMethod.length());
+                                    }
+                                    addressSize = Math.max(addressSize, currentAddress.length());
+                                    methodStrSize = Math.max(methodStrSize, methodToStr.length());
+                                }
+
+                                Collections.sort(toLog);
+
+                                resourcesToLog.add(new Logs.LogResourceEndpointInfo(address, clazz, toLog, methodSize, methodStrSize));
+                            }
+
+                            // effective logging
+                            log.info("REST Application: " + endpoint.getEndpointInfo().getAddress() + " -> "
+                                    + ofNullable(app).map(ApplicationInfo::getResourceClass).map(Class::getName).orElse(""));
+
+                            Collections.sort(resourcesToLog);
+                            final int fClassSize = classSize;
+                            final int fAddressSize = addressSize;
+                            resourcesToLog.forEach(resource -> {
+                                log.info("     Service URI: "
+                                        + Logs.forceLength(resource.address, fAddressSize, true) + " -> "
+                                        + Logs.forceLength(resource.classname, fClassSize, true));
+
+                                resource.operations.forEach(info -> {
+                                    log.info("          "
+                                            + Logs.forceLength(info.http, resource.methodSize, false) + " "
+                                            + Logs.forceLength(info.address, fAddressSize, true) + " ->      "
+                                            + Logs.forceLength(info.method, resource.methodStrSize, true));
+                                });
+                                resource.operations.clear();
+                            });
+                            resourcesToLog.clear();
+                        });
+            }
         });
         jaxrs.setLoadOnStartup(1);
         jaxrs.setAsyncSupported(true);
         jaxrs.addMapping(builder.getJaxrsMapping());
+        ofNullable(builder.getCxfServletParams()).ifPresent(m -> m.forEach(jaxrs::setInitParameter));
     }
+
+    private static class Logs {
+        private Logs() {
+            // no-op
+        }
+
+        private static String forceLength(final String httpMethod, final int l, final boolean right) {
+            final String http;
+            if (httpMethod == null) { // subresourcelocator implies null http method
+                http = "";
+            } else {
+                http = httpMethod;
+            }
+
+            final StringBuilder builder = new StringBuilder();
+            if (!right) {
+                for (int i = 0; i < l - http.length(); i++) {
+                    builder.append(" ");
+                }
+            }
+            builder.append(http);
+            if (right) {
+                for (int i = 0; i < l - http.length(); i++) {
+                    builder.append(" ");
+                }
+            }
+            return builder.toString();
+        }
+
+        private static String toSimpleString(final Method mtd) {
+            try {
+                final StringBuilder sb = new StringBuilder();
+                final Type[] typeparms = mtd.getTypeParameters();
+                if (typeparms.length > 0) {
+                    boolean first = true;
+                    sb.append("<");
+                    for (Type typeparm : typeparms) {
+                        if (!first) {
+                            sb.append(",");
+                        }
+                        sb.append(name(typeparm));
+                        first = false;
+                    }
+                    sb.append("> ");
+                }
+
+                final Type genRetType = mtd.getGenericReturnType();
+                sb.append(name(genRetType)).append(" ");
+                sb.append(mtd.getName()).append("(");
+                final Type[] params = mtd.getGenericParameterTypes();
+                for (int j = 0; j < params.length; j++) {
+                    sb.append(name(params[j]));
+                    if (j < (params.length - 1)) {
+                        sb.append(", ");
+                    }
+                }
+                sb.append(")");
+                final Type[] exceptions = mtd.getGenericExceptionTypes();
+                if (exceptions.length > 0) {
+                    sb.append(" throws ");
+                    for (int k = 0; k < exceptions.length; k++) {
+                        sb.append(name(exceptions[k]));
+                        if (k < (exceptions.length - 1)) {
+                            sb.append(",");
+                        }
+                    }
+                }
+                return sb.toString();
+            } catch (final Exception e) {
+                return "<" + e + ">";
+            }
+        }
+
+        private static String name(final Type type) {
+            if (type instanceof Class<?>) {
+                return ((Class) type).getSimpleName().replace("java.lang.", "").replace("java.util", "");
+            } else if (type instanceof ParameterizedType) {
+                final ParameterizedType pt = (ParameterizedType) type;
+                final StringBuilder builder = new StringBuilder();
+                builder.append(name(pt.getRawType()));
+                final Type[] args = pt.getActualTypeArguments();
+                if (args != null) {
+                    builder.append("<");
+                    for (int i = 0; i < args.length; i++) {
+                        builder.append(name(args[i]));
+                        if (i < args.length - 1) {
+                            builder.append(", ");
+                        }
+                    }
+                    builder.append(">");
+                }
+                return builder.toString();
+            }
+            return type.toString();
+        }
+
+        private static String singleSlash(final String address, final String value) {
+            if (address.endsWith("/") && value.startsWith("/")) {
+                return address + value.substring(1);
+            }
+            if (!address.endsWith("/") && !value.startsWith("/")) {
+                return address + '/' + value;
+            }
+            return address + value;
+        }
+
+        private static class LogOperationEndpointInfo implements Comparable<LogOperationEndpointInfo> {
+            private final String http;
+            private final String address;
+            private final String method;
+
+            private LogOperationEndpointInfo(final String http, final String address, final String method) {
+                this.address = address;
+                this.method = method;
+
+                if (http != null) {
+                    this.http = http;
+                } else { // can happen with subresource locators
+                    this.http = "";
+                }
+            }
+
+            @Override
+            public int compareTo(final LogOperationEndpointInfo o) {
+                int compare = http.compareTo(o.http);
+                if (compare != 0) {
+                    return compare;
+                }
+
+                compare = address.compareTo(o.address);
+                if (compare != 0) {
+                    return compare;
+                }
+
+                return method.compareTo(o.method);
+            }
+        }
+
+        private static class LogResourceEndpointInfo implements Comparable<LogResourceEndpointInfo> {
+            private final String address;
+            private final String classname;
+            private final List<LogOperationEndpointInfo> operations;
+            private final int methodSize;
+            private final int methodStrSize;
+
+            private LogResourceEndpointInfo(final String address, final String classname,
+                                            final List<LogOperationEndpointInfo> operations,
+                                            final int methodSize, final int methodStrSize) {
+                this.address = address;
+                this.classname = classname;
+                this.operations = operations;
+                this.methodSize = methodSize;
+                this.methodStrSize = methodStrSize;
+            }
+
+            @Override
+            public int compareTo(final LogResourceEndpointInfo o) {
+                final int compare = address.compareTo(o.address);
+                if (compare != 0) {
+                    return compare;
+                }
+                return classname.compareTo(o.classname);
+            }
+        }
+    }
+
 }

Modified: openwebbeans/microwave/trunk/microwave-core/src/main/resources/log4j2.xml
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/microwave-core/src/main/resources/log4j2.xml?rev=1765758&r1=1765757&r2=1765758&view=diff
==============================================================================
--- openwebbeans/microwave/trunk/microwave-core/src/main/resources/log4j2.xml (original)
+++ openwebbeans/microwave/trunk/microwave-core/src/main/resources/log4j2.xml Thu Oct 20 07:18:43 2016
@@ -20,7 +20,7 @@
 <Configuration status="INFO">
   <Appenders>
     <Console name="Console" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+      <PatternLayout pattern="[%d{HH:mm:ss.SSS}][%highlight{%-5level}][%15.15t][%30.30logger] %msg%n"/>
     </Console>
   </Appenders>
   <Loggers>
@@ -29,3 +29,4 @@
     </Root>
   </Loggers>
 </Configuration>
+