added svcapi ui and camunda code
[it/otf.git] / otf-camunda / src / main / java / org / oran / otf / camunda / configuration / OTFLoggingFeature.java
diff --git a/otf-camunda/src/main/java/org/oran/otf/camunda/configuration/OTFLoggingFeature.java b/otf-camunda/src/main/java/org/oran/otf/camunda/configuration/OTFLoggingFeature.java
new file mode 100644 (file)
index 0000000..9715fc0
--- /dev/null
@@ -0,0 +1,238 @@
+/*  Copyright (c) 2019 AT&T Intellectual Property.                             #\r
+#                                                                              #\r
+#   Licensed under the Apache License, Version 2.0 (the "License");            #\r
+#   you may not use this file except in compliance with the License.           #\r
+#   You may obtain a copy of the License at                                    #\r
+#                                                                              #\r
+#       http://www.apache.org/licenses/LICENSE-2.0                             #\r
+#                                                                              #\r
+#   Unless required by applicable law or agreed to in writing, software        #\r
+#   distributed under the License is distributed on an "AS IS" BASIS,          #\r
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #\r
+#   See the License for the specific language governing permissions and        #\r
+#   limitations under the License.                                             #\r
+##############################################################################*/\r
+\r
+\r
+package org.oran.otf.camunda.configuration;\r
+\r
+import org.glassfish.jersey.logging.LoggingFeature;\r
+import org.glassfish.jersey.message.MessageUtils;\r
+\r
+import javax.ws.rs.WebApplicationException;\r
+import javax.ws.rs.client.ClientRequestContext;\r
+import javax.ws.rs.client.ClientRequestFilter;\r
+import javax.ws.rs.client.ClientResponseContext;\r
+import javax.ws.rs.client.ClientResponseFilter;\r
+import javax.ws.rs.container.ContainerRequestContext;\r
+import javax.ws.rs.container.ContainerRequestFilter;\r
+import javax.ws.rs.container.ContainerResponseContext;\r
+import javax.ws.rs.container.ContainerResponseFilter;\r
+import javax.ws.rs.core.FeatureContext;\r
+import javax.ws.rs.core.MultivaluedMap;\r
+import javax.ws.rs.ext.WriterInterceptor;\r
+import javax.ws.rs.ext.WriterInterceptorContext;\r
+import java.io.*;\r
+import java.net.URI;\r
+import java.nio.charset.Charset;\r
+import java.util.ArrayList;\r
+import java.util.Base64;\r
+import java.util.List;\r
+import java.util.Objects;\r
+import java.util.logging.Level;\r
+import java.util.logging.Logger;\r
+\r
+public class OTFLoggingFeature extends LoggingFeature implements ContainerRequestFilter, ContainerResponseFilter,\r
+        ClientRequestFilter, ClientResponseFilter, WriterInterceptor {\r
+\r
+    private static final boolean printEntity = true;\r
+    private static final int maxEntitySize = 8 * 1024;\r
+    private final Logger logger = Logger.getLogger("OTFLoggingFeature");\r
+    private static final String ENTITY_LOGGER_PROPERTY = OTFLoggingFeature.class.getName();\r
+    private static final String NOTIFICATION_PREFIX = "* ";\r
+    private static final String REQUEST_PREFIX = "> ";\r
+    private static final String RESPONSE_PREFIX = "< ";\r
+    private static final String AUTHORIZATION = "Authorization";\r
+    private static final String EQUAL = " = ";\r
+    private static final String HEADERS_SEPARATOR = ", ";\r
+    private static List<String> requestHeaders;\r
+\r
+    static {\r
+        requestHeaders = new ArrayList<>();\r
+        requestHeaders.add(AUTHORIZATION);\r
+    }\r
+\r
+    public OTFLoggingFeature(Logger logger, Level level, Verbosity verbosity, Integer maxEntitySize) {\r
+        super(logger, level, verbosity, maxEntitySize);\r
+    }\r
+\r
+    @Override\r
+    public boolean configure(FeatureContext context) {\r
+        context.register(this);\r
+        return true;\r
+    }\r
+\r
+    private Object getEmail(Object authorization){\r
+        try{\r
+            String encoded = ((String) authorization).split(" ")[1];\r
+            String decoded =  new String(Base64.getDecoder().decode(encoded));\r
+            return decoded.split(":")[0];\r
+        }\r
+        catch (Exception e){\r
+            return authorization;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void filter(final ClientRequestContext context) {\r
+        final StringBuilder b = new StringBuilder();\r
+        printHeaders(b, context.getStringHeaders());\r
+        printRequestLine(b, "Sending client request", context.getMethod(), context.getUri());\r
+\r
+        if (printEntity && context.hasEntity()) {\r
+            final OutputStream stream = new LoggingStream(b, context.getEntityStream());\r
+            context.setEntityStream(stream);\r
+            context.setProperty(ENTITY_LOGGER_PROPERTY, stream);\r
+            // not calling log(b) here - it will be called by the interceptor\r
+        } else {\r
+            log(b);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) throws IOException {\r
+        final StringBuilder b = new StringBuilder();\r
+        printResponseLine(b, "Client response received", responseContext.getStatus());\r
+\r
+        if (printEntity && responseContext.hasEntity()) {\r
+            responseContext.setEntityStream(logInboundEntity(b, responseContext.getEntityStream(),\r
+                    MessageUtils.getCharset(responseContext.getMediaType())));\r
+        }\r
+        log(b);\r
+    }\r
+\r
+    @Override\r
+    public void filter(final ContainerRequestContext context) throws IOException {\r
+        final StringBuilder b = new StringBuilder();\r
+        printHeaders(b, context.getHeaders());\r
+        printRequestLine(b, "Server has received a request", context.getMethod(), context.getUriInfo().getRequestUri());\r
+\r
+        if (printEntity && context.hasEntity()) {\r
+            context.setEntityStream(logInboundEntity(b, context.getEntityStream(), MessageUtils.getCharset(context.getMediaType())));\r
+        }\r
+        log(b);\r
+    }\r
+\r
+    @Override\r
+    public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) {\r
+        final StringBuilder b = new StringBuilder();\r
+        printResponseLine(b, "Server responded with a response", responseContext.getStatus());\r
+\r
+        if (printEntity && responseContext.hasEntity()) {\r
+            final OutputStream stream = new LoggingStream(b, responseContext.getEntityStream());\r
+            responseContext.setEntityStream(stream);\r
+            requestContext.setProperty(ENTITY_LOGGER_PROPERTY, stream);\r
+            // not calling log(b) here - it will be called by the interceptor\r
+        } else {\r
+            log(b);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void aroundWriteTo(final WriterInterceptorContext writerInterceptorContext) throws IOException, WebApplicationException {\r
+        final LoggingStream stream = (LoggingStream) writerInterceptorContext.getProperty(ENTITY_LOGGER_PROPERTY);\r
+        writerInterceptorContext.proceed();\r
+        if (stream != null) {\r
+            log(stream.getStringBuilder(MessageUtils.getCharset(writerInterceptorContext.getMediaType())));\r
+        }\r
+    }\r
+\r
+    private static class LoggingStream extends FilterOutputStream {\r
+        private final StringBuilder b;\r
+        private final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();\r
+\r
+        LoggingStream(final StringBuilder b, final OutputStream inner) {\r
+            super(inner);\r
+\r
+            this.b = b;\r
+        }\r
+\r
+        StringBuilder getStringBuilder(Charset charset) {\r
+            // write entity to the builder\r
+            final byte[] entity = byteArrayOutputStream.toByteArray();\r
+\r
+            b.append(new String(entity, 0, Math.min(entity.length, maxEntitySize), charset));\r
+            if (entity.length > maxEntitySize) {\r
+                b.append("...more...");\r
+            }\r
+            b.append('\n');\r
+\r
+            return b;\r
+        }\r
+\r
+        public void write(final int i) throws IOException {\r
+            if (byteArrayOutputStream.size() <= maxEntitySize) {\r
+                byteArrayOutputStream.write(i);\r
+            }\r
+            out.write(i);\r
+        }\r
+    }\r
+\r
+    private void printHeaders(StringBuilder b, MultivaluedMap<String, String> headers) {\r
+        for (String header : requestHeaders) {\r
+            if (Objects.nonNull(headers.get(header))) {\r
+                if(header.equalsIgnoreCase("Authorization")){\r
+                    b.append(header).append(EQUAL).append(getEmail(headers.get(header).get(0))).append(HEADERS_SEPARATOR);\r
+                }\r
+                else{\r
+                    b.append(header).append(EQUAL).append(headers.get(header)).append(HEADERS_SEPARATOR);\r
+                }\r
+            }\r
+        }\r
+        int lastIndex = b.lastIndexOf(HEADERS_SEPARATOR);\r
+        if (lastIndex != -1) {\r
+            b.delete(lastIndex, lastIndex + HEADERS_SEPARATOR.length());\r
+            b.append("\n");\r
+        }\r
+    }\r
+\r
+    private void log(final StringBuilder b) {\r
+        String message = b.toString();\r
+        if (logger != null) {\r
+            logger.info(message);\r
+        }\r
+    }\r
+\r
+    private void printRequestLine(final StringBuilder b, final String note, final String method, final URI uri) {\r
+        b.append(NOTIFICATION_PREFIX)\r
+                .append(note)\r
+                .append(" on thread ").append(Thread.currentThread().getId())\r
+                .append(REQUEST_PREFIX).append(method).append(" ")\r
+                .append(uri.toASCIIString()).append("\n");\r
+    }\r
+\r
+    private void printResponseLine(final StringBuilder b, final String note, final int status) {\r
+        b.append(NOTIFICATION_PREFIX)\r
+                .append(note)\r
+                .append(" on thread ").append(Thread.currentThread().getId())\r
+                .append(RESPONSE_PREFIX)\r
+                .append(Integer.toString(status))\r
+                .append("\n");\r
+    }\r
+\r
+    private InputStream logInboundEntity(final StringBuilder b, InputStream stream, final Charset charset) throws IOException {\r
+        if (!stream.markSupported()) {\r
+            stream = new BufferedInputStream(stream);\r
+        }\r
+        stream.mark(maxEntitySize + 1);\r
+        final byte[] entity = new byte[maxEntitySize + 1];\r
+        final int entitySize = stream.read(entity);\r
+        b.append(new String(entity, 0, Math.min(entitySize, maxEntitySize), charset));\r
+        if (entitySize > maxEntitySize) {\r
+            b.append("...more...");\r
+        }\r
+        b.append('\n');\r
+        stream.reset();\r
+        return stream;\r
+    }\r
+}
\ No newline at end of file