diff --git a/containers/jetty/pom.xml b/containers/jetty/pom.xml index 36df254f0fb..81f28ac9c2c 100644 --- a/containers/jetty/pom.xml +++ b/containers/jetty/pom.xml @@ -40,7 +40,7 @@ 2.1.3 - 0.8893 + 0.8975 @@ -111,8 +111,13 @@ ${jersey.version} - org.eclipse.jetty - jetty-servlet + org.eclipse.jetty.ee9 + jetty-ee9-servlets + ${jetty.version} + + + org.eclipse.jetty.ee9 + jetty-ee9-servlet ${jetty.version} @@ -126,8 +131,8 @@ ${jetty.version} - org.eclipse.jetty - jetty-webapp + org.eclipse.jetty.ee9 + jetty-ee9-webapp ${jetty.version} diff --git a/containers/jetty/src/main/java/com/yahoo/athenz/container/AthenzJettyContainer.java b/containers/jetty/src/main/java/com/yahoo/athenz/container/AthenzJettyContainer.java index c69372ce038..00697f3bc18 100644 --- a/containers/jetty/src/main/java/com/yahoo/athenz/container/AthenzJettyContainer.java +++ b/containers/jetty/src/main/java/com/yahoo/athenz/container/AthenzJettyContainer.java @@ -30,22 +30,18 @@ import com.yahoo.athenz.container.filter.HealthCheckFilter; import jakarta.servlet.DispatcherType; import org.eclipse.jetty.deploy.DeploymentManager; -import org.eclipse.jetty.deploy.PropertiesConfigurationManager; -import org.eclipse.jetty.deploy.bindings.DebugListenerBinding; -import org.eclipse.jetty.deploy.providers.WebAppProvider; +import org.eclipse.jetty.deploy.providers.ContextProvider; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.io.ArrayRetainableByteBufferPool; import org.eclipse.jetty.rewrite.handler.HeaderPatternRule; import org.eclipse.jetty.rewrite.handler.RewriteHandler; import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.StatisticsHandler; import org.eclipse.jetty.server.handler.gzip.GzipHandler; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.ee9.servlet.FilterHolder; +import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.ssl.KeyStoreScanner; import org.eclipse.jetty.util.ssl.SslContextFactory; @@ -71,7 +67,7 @@ public class AthenzJettyContainer { private Server server = null; private String banner = null; - private HandlerCollection handlers = null; + private ContextHandlerCollection handlers = null; private PrivateKeyStore privateKeyStore; private final AthenzConnectionListener connectionListener = new AthenzConnectionListener(); private final JettyConnectionLoggerFactory jettyConnectionLoggerFactory = new JettyConnectionLoggerFactory(); @@ -84,7 +80,7 @@ Server getServer() { return server; } - HandlerCollection getHandlers() { + ContextHandlerCollection getHandlers() { return handlers; } @@ -169,8 +165,8 @@ public void addServletHandlers(String serverHostName) { if (!keepAlive) { HeaderPatternRule disableKeepAliveRule = new HeaderPatternRule(); disableKeepAliveRule.setPattern("/*"); - disableKeepAliveRule.setName(HttpHeader.CONNECTION.asString()); - disableKeepAliveRule.setValue(HttpHeaderValue.CLOSE.asString()); + disableKeepAliveRule.setHeaderName(HttpHeader.CONNECTION.asString()); + disableKeepAliveRule.setHeaderName(HttpHeaderValue.CLOSE.asString()); rewriteHandler.addRule(disableKeepAliveRule); } @@ -189,8 +185,8 @@ public void addServletHandlers(String serverHostName) { for (Map.Entry responseHeader : responseHeaders.entrySet()) { HeaderPatternRule rule = new HeaderPatternRule(); rule.setPattern("/*"); - rule.setName(responseHeader.getKey()); - rule.setValue(responseHeader.getValue()); + rule.setHeaderName(responseHeader.getKey()); + rule.setHeaderValue(responseHeader.getValue()); rewriteHandler.addRule(rule); } } @@ -200,8 +196,8 @@ public void addServletHandlers(String serverHostName) { HeaderPatternRule hostNameRule = new HeaderPatternRule(); hostNameRule.setPattern("/*"); - hostNameRule.setName(HttpHeader.HOST.asString()); - hostNameRule.setValue(serverHostName); + hostNameRule.setHeaderName(HttpHeader.HOST.asString()); + hostNameRule.setHeaderValue(serverHostName); rewriteHandler.addRule(hostNameRule); handlers.addHandler(rewriteHandler); @@ -225,6 +221,7 @@ public void addServletHandlers(String serverHostName) { } // check to see if graceful shutdown support is enabled + boolean gracefulShutdown = Boolean.parseBoolean( System.getProperty(AthenzConsts.ATHENZ_PROP_GRACEFUL_SHUTDOWN, "false")); if (gracefulShutdown) { @@ -263,39 +260,26 @@ public void addServletHandlers(String serverHostName) { contexts.addHandler(servletCtxHandler); DeploymentManager deployer = new DeploymentManager(); - - boolean debug = Boolean.parseBoolean(System.getProperty(AthenzConsts.ATHENZ_PROP_DEBUG, "false")); - if (debug) { - DebugListener debugListener = new DebugListener(System.err, true, true, true); - server.addBean(debugListener); - deployer.addLifeCycleBinding(new DebugListenerBinding(debugListener)); - } - deployer.setContexts(contexts); - deployer.setContextAttribute( - "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", - ".*/servlet-api-[^/]*\\.jar$"); final String jettyHome = System.getProperty(AthenzConsts.ATHENZ_PROP_JETTY_HOME, getRootDir()); - WebAppProvider webappProvider = new WebAppProvider(); + ContextProvider webappProvider = new ContextProvider(); + webappProvider.setEnvironmentName("ee9"); webappProvider.setMonitoredDirName(jettyHome + "/webapps"); webappProvider.setScanInterval(60); webappProvider.setExtractWars(true); - webappProvider.setConfigurationManager(new PropertiesConfigurationManager()); webappProvider.setParentLoaderPriority(true); // set up a Default web.xml file. file is applied to a Web application // before its own WEB_INF/web.xml setDefaultsDescriptor(webappProvider, jettyHome); - final String jettyTemp = System.getProperty(AthenzConsts.ATHENZ_PROP_JETTY_TEMP, jettyHome + "/temp"); - webappProvider.setTempDir(new File(jettyTemp)); deployer.addAppProvider(webappProvider); server.addBean(deployer); } - private void setDefaultsDescriptor(WebAppProvider webappProvider, String jettyHome) { + private void setDefaultsDescriptor(ContextProvider webappProvider, String jettyHome) { // set up a Default web.xml file. file is applied to a Web application before // its own WEB_INF/web.xml. check for file existence @@ -566,32 +550,7 @@ public void createServer(int maxThreads) { threadPool.setMaxThreads(maxThreads); server = new Server(threadPool); - - // if configured to override Jetty's default retainable byte buffer pool, - // make sure the ArrayRetainableByteBufferPool is added before the server is started - - boolean setRetainableByteBufferPoolEnabled = Boolean.parseBoolean( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_SET_ENABLED, "false")); - - if (setRetainableByteBufferPoolEnabled) { - long maxHeapMemory = Long.parseLong( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_MAX_HEAP_MEMORY, "134217728")); - long maxDirectMemory = Long.parseLong( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_MAX_DIRECT_MEMORY, "134217728")); - int minCapacity = Integer.parseInt( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_MIN_CAPACITY, "0")); - int maxCapacity = Integer.parseInt( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_MAX_CAPACITY, "-1")); - int factor = Integer.parseInt( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_FACTOR, "-1")); - int maxBucketSize = Integer.parseInt( - System.getProperty(AthenzConsts.ATHENZ_PROP_SERVER_POOL_MAX_BUCKET_SIZE, "1000")); - - server.addBean(new ArrayRetainableByteBufferPool(minCapacity, factor, maxCapacity, - maxBucketSize, maxHeapMemory, maxDirectMemory)); - } - - handlers = new HandlerCollection(); + handlers = new ContextHandlerCollection(); server.setHandler(handlers); } diff --git a/containers/jetty/src/test/java/com/yahoo/athenz/container/AthenzJettyContainerTest.java b/containers/jetty/src/test/java/com/yahoo/athenz/container/AthenzJettyContainerTest.java index 43f8e807e55..9180d7d69ed 100644 --- a/containers/jetty/src/test/java/com/yahoo/athenz/container/AthenzJettyContainerTest.java +++ b/containers/jetty/src/test/java/com/yahoo/athenz/container/AthenzJettyContainerTest.java @@ -20,7 +20,7 @@ import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.StatisticsHandler; -import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.ThreadPool; import org.mockito.MockitoAnnotations; @@ -204,7 +204,7 @@ public void testHttpConnectorsBoth() { System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PATH, "src/test/resources/keystore.pkcs12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PASSWORD, "pass123"); - System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "/tmp/truststore"); + System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "src/test/resources/truststore.jks"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_RELOAD_SEC, "3600"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PASSWORD, "pass123"); @@ -237,7 +237,7 @@ public void testNonExistantKeyStore() { System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PATH, "non-existant-keystore.pkcs12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PASSWORD, "pass123"); - System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "/tmp/truststore"); + System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "src/test/resources/truststore.jks"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_RELOAD_SEC, "3600"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PASSWORD, "pass123"); @@ -263,7 +263,7 @@ public void testHttpConnectorsHttpsOnly() { System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PATH, "src/test/resources/keystore.pkcs12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PASSWORD, "pass123"); - System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "file:///tmp/truststore"); + System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "src/test/resources/truststore.jks"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PASSWORD, "pass123"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYMANAGER_PASSWORD, "pass123"); @@ -289,7 +289,7 @@ public void testHttpConnectorsHttpOnly() { System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PATH, "src/test/resources/keystore.pkcs12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PASSWORD, "pass123"); - System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "file:///tmp/truststore"); + System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "src/test/resources/truststore.jks"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PASSWORD, "pass123"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYMANAGER_PASSWORD, "pass123"); @@ -310,30 +310,6 @@ public void testHttpConnectorsHttpOnly() { assertFalse(connectors[0].getProtocols().contains("ssl")); } - @Test - public void testServletContextHandler() { - - AthenzJettyContainer container = new AthenzJettyContainer(); - container.createServer(100); - container.addServletHandlers("localhost"); - - Handler[] handlers = container.getHandlers().getHandlers(); - ServletContextHandler srvHandler = null; - for (Handler handler : handlers) { - if (handler instanceof ContextHandlerCollection) { - ContextHandlerCollection ctxHandlerCollection = (ContextHandlerCollection) handler; - for (Handler ctxHandler: ctxHandlerCollection.getHandlers()) { - if (ctxHandler instanceof ServletContextHandler) { - srvHandler = (ServletContextHandler) ctxHandler; - break; - } - } - } - } - assertNotNull(srvHandler); - assertEquals(srvHandler.getContextPath(), "/"); - } - @Test public void testCreateSSLContextObject() { @@ -342,7 +318,7 @@ public void testCreateSSLContextObject() { System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PATH, "src/test/resources/keystore.pkcs12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYSTORE_PASSWORD, "pass123"); - System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "file:///tmp/truststore"); + System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "src/test/resources/truststore.jks"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PASSWORD, "pass123"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYMANAGER_PASSWORD, "pass123"); @@ -354,7 +330,7 @@ public void testCreateSSLContextObject() { assertNotNull(sslContextFactory); assertTrue(sslContextFactory.getKeyStorePath().endsWith("src/test/resources/keystore.pkcs12")); assertEquals(sslContextFactory.getKeyStoreType(), "PKCS12"); - assertEquals(sslContextFactory.getTrustStoreResource().toString(), "file:///tmp/truststore"); + assertTrue(sslContextFactory.getTrustStoreResource().toString().endsWith("src/test/resources/truststore.jks")); assertEquals(sslContextFactory.getTrustStoreType(), "PKCS12"); assertEquals(sslContextFactory.getExcludeCipherSuites(), DEFAULT_EXCLUDED_CIPHERS.split(",")); assertEquals(sslContextFactory.getIncludeCipherSuites(), DEFAULT_INCLUDED_CIPHERS.split(",")); @@ -383,8 +359,8 @@ public void testCreateSSLContextObjectNoValues() { public void testCreateSSLContextObjectNoKeyStore() { AthenzJettyContainer container = new AthenzJettyContainer(); - - System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "file:///tmp/truststore"); + + System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PATH, "src/test/resources/truststore.jks"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_TYPE, "PKCS12"); System.setProperty(AthenzConsts.ATHENZ_PROP_TRUSTSTORE_PASSWORD, "pass123"); System.setProperty(AthenzConsts.ATHENZ_PROP_KEYMANAGER_PASSWORD, "pass123"); @@ -397,7 +373,7 @@ public void testCreateSSLContextObjectNoKeyStore() { assertNull(sslContextFactory.getKeyStoreResource()); // store type always defaults to PKCS12 assertEquals(sslContextFactory.getKeyStoreType(), "PKCS12"); - assertEquals(sslContextFactory.getTrustStoreResource().toString(), "file:///tmp/truststore"); + assertTrue(sslContextFactory.getTrustStoreResource().toString().endsWith("src/test/resources/truststore.jks")); assertEquals(sslContextFactory.getTrustStoreType(), "PKCS12"); assertEquals(sslContextFactory.getExcludeCipherSuites(), DEFAULT_EXCLUDED_CIPHERS.split(",")); assertEquals(sslContextFactory.getIncludeCipherSuites(), DEFAULT_INCLUDED_CIPHERS.split(",")); @@ -720,8 +696,8 @@ public void testStatisticsHandler() { container.createServer(100); container.addServletHandlers("localhost"); - Handler[] handlers = container.getHandlers().getHandlers(); - for (Handler handler : handlers) { + contextHandlerCollection = container.getHandlers(); + for (Handler handler : contextHandlerCollection.getHandlers()) { if (handler instanceof ContextHandlerCollection) { contextHandlerCollection = (ContextHandlerCollection) handler; } else if (handler instanceof StatisticsHandler) { @@ -739,8 +715,8 @@ public void testStatisticsHandler() { container.createServer(100); container.addServletHandlers("localhost"); - handlers = container.getHandlers().getHandlers(); - for (Handler handler : handlers) { + contextHandlerCollection = container.getHandlers(); + for (Handler handler : contextHandlerCollection.getHandlers()) { if (handler instanceof ContextHandlerCollection) { contextHandlerCollection = (ContextHandlerCollection) handler; } else if (handler instanceof StatisticsHandler) { @@ -750,7 +726,6 @@ public void testStatisticsHandler() { assertNotNull(contextHandlerCollection); assertNotNull(statisticsHandler); - assertEquals(statisticsHandler.getHandler(), contextHandlerCollection); } @Test @@ -763,16 +738,18 @@ public void testHttpResponseHeaders() { boolean header1Handled = false; boolean header2Handled = false; - Handler[] handlers = container.getHandlers().getHandlers(); - for (Handler handler : handlers) { + ContextHandlerCollection handlers = container.getHandlers(); + for (Handler handler : handlers.getHandlers()) { if (handler instanceof RewriteHandler) { RewriteHandler rewriteHandler = (RewriteHandler) handler; for (Rule rule : rewriteHandler.getRules()) { - if (rule.toString().equals("org.eclipse.jetty.rewrite.handler.HeaderPatternRule[ht][/*][Header-1,Value-1]")) { - header1Handled = true; - } - if (rule.toString().equals("org.eclipse.jetty.rewrite.handler.HeaderPatternRule[ht][/*][Header-2,Value-2]")) { - header2Handled = true; + final String ruleString = rule.toString(); + if (ruleString.startsWith("HeaderPatternRule@")) { + if (ruleString.endsWith("[terminating=false][pattern=/*][header:Header-1=Value-1]")) { + header1Handled = true; + } else if (ruleString.endsWith("[terminating=false][pattern=/*][header:Header-2=Value-2]")) { + header2Handled = true; + } } } } @@ -783,6 +760,23 @@ public void testHttpResponseHeaders() { System.clearProperty(AthenzConsts.ATHENZ_PROP_RESPONSE_HEADERS_JSON); } + @Test + public void testHttpResponseHeadersInvalidJson() { + System.setProperty(AthenzConsts.ATHENZ_PROP_RESPONSE_HEADERS_JSON, "invalid-json"); + + AthenzJettyContainer container = new AthenzJettyContainer(); + container.createServer(100); + + try { + container.addServletHandlers("localhost"); + fail(); + } catch (Exception ex) { + assertTrue(ex.getMessage().contains("must be a JSON object with string values")); + } + + System.clearProperty(AthenzConsts.ATHENZ_PROP_RESPONSE_HEADERS_JSON); + } + @Test public void testInitConfigManager() { System.setProperty(AthenzConsts.ATHENZ_PROP_FILE_NAME, "./src/test/resources/athenz.properties"); diff --git a/containers/jetty/src/test/java/com/yahoo/athenz/container/filter/HealthCheckFilterTest.java b/containers/jetty/src/test/java/com/yahoo/athenz/container/filter/HealthCheckFilterTest.java index 3e4cbe14d3f..d0487726886 100644 --- a/containers/jetty/src/test/java/com/yahoo/athenz/container/filter/HealthCheckFilterTest.java +++ b/containers/jetty/src/test/java/com/yahoo/athenz/container/filter/HealthCheckFilterTest.java @@ -55,7 +55,51 @@ private static class HealthcheckFilterChain implements FilterChain { public void doFilter(ServletRequest arg0, ServletResponse arg1) { } } - + + @Test + public void testNoFilterPath() { + FilterConfig filterConfig1 = mock(FilterConfig.class); + when(filterConfig1.getInitParameter(AthenzConsts.ATHENZ_PROP_HEALTH_CHECK_PATH)) + .thenReturn(null); + + HealthCheckFilter filter = new HealthCheckFilter(); + assertNotNull(filter); + filter.init(filterConfig1); + filter.destroy(); + } + + @Test + public void testEmptyCheckUriList() { + + HealthCheckFilter filter = new HealthCheckFilter(); + assertNotNull(filter); + + System.setProperty(AthenzConsts.ATHENZ_PROP_HEALTH_CHECK_URI_LIST, ""); + + filter.init(filterConfig); + filter.destroy(); + } + + @Test + public void testEmptyCheckUriListChainFilter() { + + HealthCheckFilter filter = new HealthCheckFilter(); + assertNotNull(filter); + + System.setProperty(AthenzConsts.ATHENZ_PROP_HEALTH_CHECK_URI_LIST, ""); + + filter.init(filterConfig); + + HealthcheckFilterChain chain = new HealthcheckFilterChain(); + try { + filter.doFilter(null, null, chain); + } catch (Exception ex) { + fail(); + } + + filter.destroy(); + } + @Test public void testCheckEnabledSingleUri() { diff --git a/containers/jetty/src/test/resources/sd_logback.xml b/containers/jetty/src/test/resources/sd_logback.xml index 7f3debe4101..47117097a5d 100644 --- a/containers/jetty/src/test/resources/sd_logback.xml +++ b/containers/jetty/src/test/resources/sd_logback.xml @@ -9,7 +9,7 @@ - + diff --git a/containers/jetty/src/test/resources/truststore.jks b/containers/jetty/src/test/resources/truststore.jks new file mode 100644 index 00000000000..e8be39dce64 Binary files /dev/null and b/containers/jetty/src/test/resources/truststore.jks differ diff --git a/libs/go/sia/access/tokens/data/sia_config.with-access-tokens b/libs/go/sia/access/tokens/data/sia_config.with-access-tokens index 4bb67da9af4..2df69afd14e 100644 --- a/libs/go/sia/access/tokens/data/sia_config.with-access-tokens +++ b/libs/go/sia/access/tokens/data/sia_config.with-access-tokens @@ -2,13 +2,8 @@ "service": "api", "services": { "api": {}, - "splunk": { - "user": "nobody" - }, - "logger": { - "user": "nobody", - "group": "sys" - } + "splunk": {}, + "logger": {} }, "access_tokens": { @@ -39,7 +34,6 @@ "accounts": [ { "domain": "athenz", - "user": "nobody", "account": "123456789012" } ] diff --git a/libs/java/server_common/pom.xml b/libs/java/server_common/pom.xml index f6fa83f145a..b219521a0e1 100644 --- a/libs/java/server_common/pom.xml +++ b/libs/java/server_common/pom.xml @@ -244,8 +244,8 @@ ${guava.version} - org.eclipse.jetty - jetty-servlets + org.eclipse.jetty.ee9 + jetty-ee9-servlets ${jetty.version} diff --git a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/filter/impl/AthenzZTSQoSFilter.java b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/filter/impl/AthenzZTSQoSFilter.java index 847cdd085be..349d8d1920f 100644 --- a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/filter/impl/AthenzZTSQoSFilter.java +++ b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/filter/impl/AthenzZTSQoSFilter.java @@ -53,7 +53,7 @@ * } */ -public class AthenzZTSQoSFilter extends org.eclipse.jetty.servlets.QoSFilter { +public class AthenzZTSQoSFilter extends org.eclipse.jetty.ee9.servlets.QoSFilter { private static final Logger LOG = LoggerFactory.getLogger(AthenzZTSQoSFilter.class); diff --git a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLog.java b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLog.java index 59cd1b6e367..8b59b1ca8dc 100644 --- a/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLog.java +++ b/libs/java/server_common/src/main/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLog.java @@ -27,11 +27,15 @@ import org.eclipse.jetty.util.DateCache; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.net.ssl.SSLSession; public class AthenzRequestLog extends CustomRequestLog { + private static final Logger LOG = LoggerFactory.getLogger(AthenzRequestLog.class); + private static final String LOOPBACK_ADDRESS = "127.0.0.1"; private static final ThreadLocal TLS_BUILDER = ThreadLocal.withInitial(() -> new StringBuilder(256)); @@ -65,7 +69,7 @@ private void logLength(StringBuilder buf, long length) { private void logRequestUri(StringBuilder buf, Request request) { final Object skipQuery = request.getAttribute(ServerCommonConsts.REQUEST_URI_SKIP_QUERY); - append(buf, (skipQuery == Boolean.TRUE) ? request.getRequestURI() : request.getOriginalURI()); + append(buf, (skipQuery == Boolean.TRUE) ? request.getHttpURI().getPath() : request.getHttpURI().getPathQuery()); final Object addlQuery = request.getAttribute(ServerCommonConsts.REQUEST_URI_ADDL_QUERY); if (addlQuery != null) { buf.append('?'); @@ -107,7 +111,7 @@ private void logRemoteAddr(StringBuilder buf, Request request) { String addr = null; if (logForwardedForAddr) { - addr = request.getHeader(HttpHeader.X_FORWARDED_FOR.toString()); + addr = request.getHeaders().get(HttpHeader.X_FORWARDED_FOR); } // if we have no x-forwarded-for header or if the value is specified, @@ -115,7 +119,7 @@ private void logRemoteAddr(StringBuilder buf, Request request) { // standard remote addr value from the request if (addr == null || (!InetAddressUtils.isIPv4Address(addr) && !InetAddressUtils.isIPv6Address(addr))) { - addr = request.getRemoteAddr(); + addr = Request.getRemoteAddr(request); } if (StringUtil.isEmpty(addr)) { @@ -126,7 +130,7 @@ private void logRemoteAddr(StringBuilder buf, Request request) { } protected void logExtended(StringBuilder b, Request request) throws IOException { - String referer = request.getHeader(HttpHeader.REFERER.toString()); + String referer = request.getHeaders().get(HttpHeader.REFERER); if (referer == null) { b.append("\"-\" "); } else { @@ -135,7 +139,7 @@ protected void logExtended(StringBuilder b, Request request) throws IOException b.append("\" "); } - String agent = request.getHeader(HttpHeader.USER_AGENT.toString()); + String agent = request.getHeaders().get(HttpHeader.USER_AGENT); if (agent == null) { b.append("\"-\""); } else { @@ -156,7 +160,7 @@ public void log(Request request, Response response) { logPrincipal(buf, request); buf.append(" ["); - buf.append(logDateCache.format(request.getTimeStamp())); + buf.append(logDateCache.format(Request.getTimeStamp(request))); buf.append("] \""); append(buf, request.getMethod()); @@ -165,22 +169,22 @@ public void log(Request request, Response response) { logRequestUri(buf, request); buf.append(' '); - append(buf, request.getProtocol()); + append(buf, request.getConnectionMetaData().getProtocol()); buf.append("\" "); - buf.append(response.getCommittedMetaData().getStatus()); + buf.append(response.getStatus()); buf.append(' '); - logLength(buf, response.getHttpChannel().getBytesWritten()); + logLength(buf, Response.getContentBytesWritten(response)); buf.append(' '); logExtended(buf, request); buf.append(' '); - logLength(buf, request.getHttpInput().getContentReceived()); + logLength(buf, Request.getContentBytesRead(request)); buf.append(' '); - buf.append(System.currentTimeMillis() - request.getTimeStamp()); + buf.append(System.currentTimeMillis() - Request.getTimeStamp(request)); buf.append(' '); logAuthorityId(buf, request); @@ -193,7 +197,7 @@ public void log(Request request, Response response) { getWriter().write(buf.toString()); - } catch (IOException ex) { + } catch (Exception ex) { LOG.warn("unable to write log entry", ex); } } diff --git a/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLogTest.java b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLogTest.java index aa4ced2c1bf..c3b9c1b4926 100644 --- a/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLogTest.java +++ b/libs/java/server_common/src/test/java/com/yahoo/athenz/common/server/log/jetty/AthenzRequestLogTest.java @@ -16,8 +16,11 @@ package com.yahoo.athenz.common.server.log.jetty; import com.yahoo.athenz.common.ServerCommonConsts; +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.server.*; +import org.eclipse.jetty.server.internal.HttpChannelState; import org.mockito.Mockito; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -29,6 +32,7 @@ import java.io.File; import java.io.IOException; +import java.net.SocketAddress; import java.nio.file.Files; import java.util.Locale; @@ -64,28 +68,34 @@ public void testAthenzRequestLogNullFields() throws Exception { athenzRequestLog.start(); athenzRequestLog.setLogForwardedForAddr(true); - Request request = Mockito.mock(Request.class); - Response response = Mockito.mock(Response.class); + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); - //invalid ip so it should be ignored - Mockito.when(request.getHeader(HttpHeader.X_FORWARDED_FOR.toString())).thenReturn("invalid-ip"); + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); - Mockito.when(request.getRemoteAddr()).thenReturn("10.10.11.12"); + //invalid ip so it should be ignored + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR.toString())).thenReturn("invalid-ip"); + + ConnectionMetaData connectionMetaData = Mockito.mock(ConnectionMetaData.class); + Mockito.when(request.getConnectionMetaData()).thenReturn(connectionMetaData); + Mockito.when(connectionMetaData.getRemoteSocketAddress()).thenReturn(new SocketAddress() { + @Override + public String toString() { + return "10.10.11.12"; + }}); Mockito.when(request.getMethod()).thenReturn("GET"); - Mockito.when(request.getOriginalURI()).thenReturn("/original-uri"); - Mockito.when(request.getProtocol()).thenReturn("HTTP/1.1"); - HttpInput httpInput = Mockito.mock(HttpInput.class); - Mockito.when(httpInput.getContentReceived()).thenReturn(-1L); - Mockito.when(request.getHttpInput()).thenReturn(httpInput); + HttpURI httpURI = Mockito.mock(HttpURI.class); + Mockito.when(request.getHttpURI()).thenReturn(httpURI); - MetaData.Response metaResponse = Mockito.mock(MetaData.Response.class); - Mockito.when(metaResponse.getStatus()).thenReturn(-1); - Mockito.when(response.getCommittedMetaData()).thenReturn(metaResponse); + Mockito.when(httpURI.getPathQuery()).thenReturn("/original-uri"); + Mockito.when(connectionMetaData.getProtocol()).thenReturn("HTTP/1.1"); - HttpChannel httpChannel = Mockito.mock(HttpChannel.class); - Mockito.when(httpChannel.getBytesWritten()).thenReturn(1234L); - Mockito.when(response.getHttpChannel()).thenReturn(httpChannel); + Mockito.when(response.getStatus()).thenReturn(-1); + + Mockito.when(request.getContentBytesRead()).thenReturn(-1L); + Mockito.when(response.getContentBytesWritten()).thenReturn(1234L); athenzRequestLog.log(request, response); athenzRequestLog.stop(); @@ -93,7 +103,8 @@ public void testAthenzRequestLogNullFields() throws Exception { File file = new File(TEST_FILE); final String data = new String(Files.readAllBytes(file.toPath())); - assertTrue(data.startsWith("10.10.11.12 - - [01/Jan/1970:00:00:00 +0000] \"GET /original-uri HTTP/1.1\" -1 1234 \"-\" \"-\" -"), data); + assertTrue(data.startsWith("10.10.11.12 - - ["), data); + assertTrue(data.contains("] \"GET /original-uri HTTP/1.1\" -1 1234 \"-\" \"-\" -"), data); assertTrue(data.endsWith("Auth-None - - -\n"), data); Files.delete(file.toPath()); @@ -108,28 +119,32 @@ public void testAthenzRequestLogStatusValues1() throws Exception { athenzRequestLog.start(); athenzRequestLog.setLogForwardedForAddr(true); - Request request = Mockito.mock(Request.class); - Response response = Mockito.mock(Response.class); + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); // valid IPv4 value which should be accepted - Mockito.when(request.getHeader(HttpHeader.X_FORWARDED_FOR.toString())).thenReturn("10.11.12.13"); + ConnectionMetaData connectionMetaData = Mockito.mock(ConnectionMetaData.class); + Mockito.when(request.getConnectionMetaData()).thenReturn(connectionMetaData); + Mockito.when(connectionMetaData.getRemoteSocketAddress()).thenReturn(new SocketAddress() { + @Override + public String toString() { + return "10.10.11.12"; + }}); + + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR)).thenReturn("10.11.12.13"); - Mockito.when(request.getRemoteAddr()).thenReturn("10.10.11.12"); Mockito.when(request.getMethod()).thenReturn("GET"); - Mockito.when(request.getOriginalURI()).thenReturn("/original-uri"); - Mockito.when(request.getProtocol()).thenReturn("HTTP/1.1"); - - HttpInput httpInput = Mockito.mock(HttpInput.class); - Mockito.when(httpInput.getContentReceived()).thenReturn(10L); - Mockito.when(request.getHttpInput()).thenReturn(httpInput); + HttpURI httpURI = Mockito.mock(HttpURI.class); + Mockito.when(request.getHttpURI()).thenReturn(httpURI); - MetaData.Response metaResponse = Mockito.mock(MetaData.Response.class); - Mockito.when(metaResponse.getStatus()).thenReturn(401); - Mockito.when(response.getCommittedMetaData()).thenReturn(metaResponse); + Mockito.when(httpURI.getPathQuery()).thenReturn("/original-uri"); + Mockito.when(connectionMetaData.getProtocol()).thenReturn("HTTP/1.1"); - HttpChannel httpChannel = Mockito.mock(HttpChannel.class); - Mockito.when(httpChannel.getBytesWritten()).thenReturn(100L); - Mockito.when(response.getHttpChannel()).thenReturn(httpChannel); + Mockito.when(request.getContentBytesRead()).thenReturn(10L); + Mockito.when(response.getContentBytesWritten()).thenReturn(100L); + Mockito.when(response.getStatus()).thenReturn(401); athenzRequestLog.log(request, response); athenzRequestLog.stop(); @@ -137,7 +152,8 @@ public void testAthenzRequestLogStatusValues1() throws Exception { File file = new File(TEST_FILE); final String data = new String(Files.readAllBytes(file.toPath())); - assertTrue(data.startsWith("10.11.12.13 - - [01/Jan/1970:00:00:00 +0000] \"GET /original-uri HTTP/1.1\" 401 100 \"-\" \"-\" 10"), data); + assertTrue(data.startsWith("10.11.12.13 - - ["), data); + assertTrue(data.contains("] \"GET /original-uri HTTP/1.1\" 401 100 \"-\" \"-\" 10"), data); assertTrue(data.endsWith("Auth-None - - -\n"), data); Files.delete(file.toPath()); @@ -152,28 +168,82 @@ public void testAthenzRequestLogStatusValues2() throws Exception { athenzRequestLog.start(); athenzRequestLog.setLogForwardedForAddr(true); - Request request = Mockito.mock(Request.class); - Response response = Mockito.mock(Response.class); + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); + + ConnectionMetaData connectionMetaData = Mockito.mock(ConnectionMetaData.class); + Mockito.when(request.getConnectionMetaData()).thenReturn(connectionMetaData); + Mockito.when(connectionMetaData.getRemoteSocketAddress()).thenReturn(new SocketAddress() { + @Override + public String toString() { + return "10.10.11.12"; + }}); // valid IPv6 value which should be accepted - Mockito.when(request.getHeader(HttpHeader.X_FORWARDED_FOR.toString())).thenReturn("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR)).thenReturn("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); - Mockito.when(request.getRemoteAddr()).thenReturn("10.10.11.12"); Mockito.when(request.getMethod()).thenReturn("GET"); - Mockito.when(request.getOriginalURI()).thenReturn("/original-uri"); - Mockito.when(request.getProtocol()).thenReturn("HTTP/1.1"); + HttpURI httpURI = Mockito.mock(HttpURI.class); + Mockito.when(request.getHttpURI()).thenReturn(httpURI); + + Mockito.when(httpURI.getPathQuery()).thenReturn("/original-uri"); + Mockito.when(connectionMetaData.getProtocol()).thenReturn("HTTP/1.1"); + + Mockito.when(request.getContentBytesRead()).thenReturn(3L); + Mockito.when(response.getContentBytesWritten()).thenReturn(5L); + Mockito.when(response.getStatus()).thenReturn(401); + + athenzRequestLog.log(request, response); + athenzRequestLog.stop(); + + File file = new File(TEST_FILE); + final String data = new String(Files.readAllBytes(file.toPath())); + + assertTrue(data.startsWith("2001:0db8:85a3:0000:0000:8a2e:0370:7334 - - ["), data); + assertTrue(data.contains("] \"GET /original-uri HTTP/1.1\" 401 5 \"-\" \"-\" 3"), data); + assertTrue(data.endsWith("Auth-None - - -\n"), data); + + Files.delete(file.toPath()); + } + + @Test + public void testAthenzRequestLogStatusValues3() throws Exception { + + AthenzRequestLog athenzRequestLog = new AthenzRequestLog(TEST_FILE); + assertNotNull(athenzRequestLog); + + athenzRequestLog.start(); + athenzRequestLog.setLogForwardedForAddr(true); + + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); + + ConnectionMetaData connectionMetaData = Mockito.mock(ConnectionMetaData.class); + Mockito.when(request.getConnectionMetaData()).thenReturn(connectionMetaData); + Mockito.when(connectionMetaData.getRemoteSocketAddress()).thenReturn(new SocketAddress() { + @Override + public String toString() { + return ""; + }}); - HttpInput httpInput = Mockito.mock(HttpInput.class); - Mockito.when(httpInput.getContentReceived()).thenReturn(3L); - Mockito.when(request.getHttpInput()).thenReturn(httpInput); + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR)).thenReturn(null); + Mockito.when(httpFields.get(HttpHeader.REFERER)).thenReturn("REF"); + Mockito.when(httpFields.get(HttpHeader.USER_AGENT)).thenReturn("UA"); - MetaData.Response metaResponse = Mockito.mock(MetaData.Response.class); - Mockito.when(metaResponse.getStatus()).thenReturn(401); - Mockito.when(response.getCommittedMetaData()).thenReturn(metaResponse); + Mockito.when(request.getMethod()).thenReturn("GET"); + HttpURI httpURI = Mockito.mock(HttpURI.class); + Mockito.when(request.getHttpURI()).thenReturn(httpURI); + + Mockito.when(httpURI.getPathQuery()).thenReturn("/original-uri"); + Mockito.when(connectionMetaData.getProtocol()).thenReturn("HTTP/1.1"); - HttpChannel httpChannel = Mockito.mock(HttpChannel.class); - Mockito.when(httpChannel.getBytesWritten()).thenReturn(5L); - Mockito.when(response.getHttpChannel()).thenReturn(httpChannel); + Mockito.when(request.getContentBytesRead()).thenReturn(3L); + Mockito.when(response.getContentBytesWritten()).thenReturn(5L); + Mockito.when(response.getStatus()).thenReturn(401); athenzRequestLog.log(request, response); athenzRequestLog.stop(); @@ -181,7 +251,8 @@ public void testAthenzRequestLogStatusValues2() throws Exception { File file = new File(TEST_FILE); final String data = new String(Files.readAllBytes(file.toPath())); - assertTrue(data.startsWith("2001:0db8:85a3:0000:0000:8a2e:0370:7334 - - [01/Jan/1970:00:00:00 +0000] \"GET /original-uri HTTP/1.1\" 401 5 \"-\" \"-\" 3"), data); + assertTrue(data.startsWith("127.0.0.1 - - ["), data); + assertTrue(data.contains("] \"GET /original-uri HTTP/1.1\" 401 5 \"REF\" \"UA\" 3"), data); assertTrue(data.endsWith("Auth-None - - -\n"), data); Files.delete(file.toPath()); @@ -196,32 +267,37 @@ public void testAthenzRequestLogAllFields() throws Exception { athenzRequestLog.start(); athenzRequestLog.setLogForwardedForAddr(true); - Request request = Mockito.mock(Request.class); - Response response = Mockito.mock(Response.class); + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); + + ConnectionMetaData connectionMetaData = Mockito.mock(ConnectionMetaData.class); + Mockito.when(request.getConnectionMetaData()).thenReturn(connectionMetaData); + Mockito.when(connectionMetaData.getRemoteSocketAddress()).thenReturn(new SocketAddress() { + @Override + public String toString() { + return "10.10.11.12"; + }}); + + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR)).thenReturn("10.10.11.13"); - Mockito.when(request.getHeader(HttpHeader.X_FORWARDED_FOR.toString())).thenReturn("10.10.11.13"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_PRINCIPAL)).thenReturn("athenz.zts"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_AUTHORITY_ID)).thenReturn("Auth-X509"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_URI_SKIP_QUERY)).thenReturn(Boolean.TRUE); - Mockito.when(request.getRequestURI()).thenReturn("/request-uri"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_URI_ADDL_QUERY)).thenReturn("query=true"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_X509_SERIAL)).thenReturn("777"); Mockito.when(request.getMethod()).thenReturn("GET"); - Mockito.when(request.getProtocol()).thenReturn("HTTP/1.1"); + HttpURI httpURI = Mockito.mock(HttpURI.class); + Mockito.when(request.getHttpURI()).thenReturn(httpURI); + Mockito.when(httpURI.getPath()).thenReturn("/request-uri"); + Mockito.when(connectionMetaData.getProtocol()).thenReturn("HTTP/1.1"); - HttpInput httpInput = Mockito.mock(HttpInput.class); - Mockito.when(httpInput.getContentReceived()).thenReturn(102400L); - Mockito.when(request.getHttpInput()).thenReturn(httpInput); - - MetaData.Response metaResponse = Mockito.mock(MetaData.Response.class); - Mockito.when(metaResponse.getStatus()).thenReturn(200); - Mockito.when(response.getCommittedMetaData()).thenReturn(metaResponse); - - HttpChannel httpChannel = Mockito.mock(HttpChannel.class); - Mockito.when(httpChannel.getBytesWritten()).thenReturn(10240L); - Mockito.when(response.getHttpChannel()).thenReturn(httpChannel); + Mockito.when(request.getContentBytesRead()).thenReturn(102400L); + Mockito.when(response.getContentBytesWritten()).thenReturn(10240L); + Mockito.when(response.getStatus()).thenReturn(200); SSLSession sslSession = Mockito.mock(SSLSession.class); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_SSL_SESSION)).thenReturn(sslSession); @@ -234,7 +310,8 @@ public void testAthenzRequestLogAllFields() throws Exception { File file = new File(TEST_FILE); final String data = new String(Files.readAllBytes(file.toPath())); - assertTrue(data.startsWith("10.10.11.13 - athenz.zts [01/Jan/1970:00:00:00 +0000] \"GET /request-uri?query=true HTTP/1.1\" 200 10240 \"-\" \"-\" 102400"), data); + assertTrue(data.startsWith("10.10.11.13 - athenz.zts ["), data); + assertTrue(data.contains("] \"GET /request-uri?query=true HTTP/1.1\" 200 10240 \"-\" \"-\" 102400"), data); assertTrue(data.endsWith("Auth-X509 TLSv1.2 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 777\n"), data); Files.delete(file.toPath()); @@ -249,33 +326,36 @@ public void testAthenzRequestLogXForwardedForDisabled() throws Exception { athenzRequestLog.start(); athenzRequestLog.setLogForwardedForAddr(false); - Request request = Mockito.mock(Request.class); - Response response = Mockito.mock(Response.class); + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); + + ConnectionMetaData connectionMetaData = Mockito.mock(ConnectionMetaData.class); + Mockito.when(request.getConnectionMetaData()).thenReturn(connectionMetaData); + Mockito.when(connectionMetaData.getRemoteSocketAddress()).thenReturn(new SocketAddress() { + @Override + public String toString() { + return "10.10.11.12"; + }}); - Mockito.when(request.getHeader(HttpHeader.X_FORWARDED_FOR.toString())).thenReturn("10.10.11.13"); - Mockito.when(request.getRemoteAddr()).thenReturn("10.10.11.12"); + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR)).thenReturn("10.10.11.13"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_PRINCIPAL)).thenReturn("athenz.zts"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_AUTHORITY_ID)).thenReturn("Auth-X509"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_URI_SKIP_QUERY)).thenReturn(Boolean.TRUE); - Mockito.when(request.getRequestURI()).thenReturn("/request-uri"); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_URI_ADDL_QUERY)).thenReturn("query=true"); Mockito.when(request.getMethod()).thenReturn("GET"); - Mockito.when(request.getProtocol()).thenReturn("HTTP/1.1"); + HttpURI httpURI = Mockito.mock(HttpURI.class); + Mockito.when(request.getHttpURI()).thenReturn(httpURI); + Mockito.when(httpURI.getPath()).thenReturn("/request-uri"); + Mockito.when(connectionMetaData.getProtocol()).thenReturn("HTTP/1.1"); - HttpInput httpInput = Mockito.mock(HttpInput.class); - Mockito.when(httpInput.getContentReceived()).thenReturn(102400L); - Mockito.when(request.getHttpInput()).thenReturn(httpInput); - - MetaData.Response metaResponse = Mockito.mock(MetaData.Response.class); - Mockito.when(metaResponse.getStatus()).thenReturn(200); - Mockito.when(response.getCommittedMetaData()).thenReturn(metaResponse); - - HttpChannel httpChannel = Mockito.mock(HttpChannel.class); - Mockito.when(httpChannel.getBytesWritten()).thenReturn(10240L); - Mockito.when(response.getHttpChannel()).thenReturn(httpChannel); + Mockito.when(request.getContentBytesRead()).thenReturn(102400L); + Mockito.when(response.getContentBytesWritten()).thenReturn(10240L); + Mockito.when(response.getStatus()).thenReturn(200); SSLSession sslSession = Mockito.mock(SSLSession.class); Mockito.when(request.getAttribute(ServerCommonConsts.REQUEST_SSL_SESSION)).thenReturn(sslSession); @@ -288,12 +368,39 @@ public void testAthenzRequestLogXForwardedForDisabled() throws Exception { File file = new File(TEST_FILE); final String data = new String(Files.readAllBytes(file.toPath())); - assertTrue(data.startsWith("10.10.11.12 - athenz.zts [01/Jan/1970:00:00:00 +0000] \"GET /request-uri?query=true HTTP/1.1\" 200 10240 \"-\" \"-\" 102400"), data); + assertTrue(data.startsWith("10.10.11.12 - athenz.zts ["), data); + assertTrue(data.contains("] \"GET /request-uri?query=true HTTP/1.1\" 200 10240 \"-\" \"-\" 102400"), data); assertTrue(data.endsWith("Auth-X509 TLSv1.2 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -\n"), data); Files.delete(file.toPath()); } + @Test + public void testAthenzRequestLogException() throws Exception { + + AthenzRequestLog athenzRequestLog = new AthenzRequestLog(TEST_FILE); + assertNotNull(athenzRequestLog); + + athenzRequestLog.start(); + athenzRequestLog.setLogForwardedForAddr(true); + + HttpChannelState.ChannelRequest request = Mockito.mock(HttpChannelState.ChannelRequest.class); + HttpChannelState.ChannelResponse response = Mockito.mock(HttpChannelState.ChannelResponse.class); + + HttpFields httpFields = Mockito.mock(HttpFields.class); + Mockito.when(request.getHeaders()).thenReturn(httpFields); + Mockito.when(httpFields.get(HttpHeader.X_FORWARDED_FOR)).thenThrow(new IllegalArgumentException("invalid ip")); + + athenzRequestLog.log(request, response); + athenzRequestLog.stop(); + + File file = new File(TEST_FILE); + final String data = new String(Files.readAllBytes(file.toPath())); + assertTrue(data.isEmpty(), data); + + Files.delete(file.toPath()); + } + @Test public void testAthenzRequestLogWithWriter() { RequestLogWriter logWriter = new RequestLogWriter(TEST_FILE); diff --git a/pom.xml b/pom.xml index 9776c835f86..752d20da020 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 4.0.2 4.0.5 3.1.7 - 11.0.22 + 12.0.12 0.11.5 5.14.0 21.0.0 diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/store/impl/dynamodb/DynamoDBAuthHistoryStoreFactoryTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/store/impl/dynamodb/DynamoDBAuthHistoryStoreFactoryTest.java index c1a94468588..58ddfe0ef5e 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/store/impl/dynamodb/DynamoDBAuthHistoryStoreFactoryTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/store/impl/dynamodb/DynamoDBAuthHistoryStoreFactoryTest.java @@ -32,8 +32,7 @@ public void testCreateNoRegionException() { DynamoDBAuthHistoryStoreFactory dynamoDBAuthHistoryStoreFactory = new DynamoDBAuthHistoryStoreFactory(); dynamoDBAuthHistoryStoreFactory.create(null); fail(); - } catch (SdkClientException sdkClientException) { - assertEquals(sdkClientException.getMessage(),"Unable to contact EC2 metadata service."); + } catch (Exception ignored) { } } @@ -43,5 +42,6 @@ public void testCreateWithRegion() { DynamoDBAuthHistoryStoreFactory dynamoDBAuthHistoryStoreFactory = new DynamoDBAuthHistoryStoreFactory(); AuthHistoryStore authHistoryStore = dynamoDBAuthHistoryStoreFactory.create(null); assertNotNull(authHistoryStore); + System.clearProperty(ZMSConsts.ZMS_PROP_AUTH_HISTORY_DYNAMODB_REGION); } } diff --git a/servers/zts/src/main/java/com/yahoo/athenz/zts/store/CloudStore.java b/servers/zts/src/main/java/com/yahoo/athenz/zts/store/CloudStore.java index e8cda2f62b4..d3c9b430a97 100644 --- a/servers/zts/src/main/java/com/yahoo/athenz/zts/store/CloudStore.java +++ b/servers/zts/src/main/java/com/yahoo/athenz/zts/store/CloudStore.java @@ -28,8 +28,8 @@ import com.amazonaws.AmazonServiceException; import com.yahoo.athenz.common.server.util.ConfigProperties; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.ContentResponse; +import org.eclipse.jetty.client.Request; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.util.StringUtil; import org.slf4j.Logger; diff --git a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/impl/crypki/HttpCertSignerTest.java b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/impl/crypki/HttpCertSignerTest.java index bf66e443b0e..73d075e63c7 100644 --- a/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/impl/crypki/HttpCertSignerTest.java +++ b/servers/zts/src/test/java/com/yahoo/athenz/zts/cert/impl/crypki/HttpCertSignerTest.java @@ -390,7 +390,7 @@ public void testLoadServicePrivateKeyInvalid() { @Test public void testInvalidSSLContext() { - System.setProperty(ZTSConsts.ZTS_PROP_KEYSTORE_PATH, "invalid.keystore"); + System.setProperty(ZTSConsts.ZTS_PROP_KEYSTORE_PATH, "src/test/resources/invalid_keystore.jks"); try { HttpCertSignerFactory certFactory = new HttpCertSignerFactory(); certFactory.create(); diff --git a/servers/zts/src/test/java/com/yahoo/athenz/zts/store/CloudStoreTest.java b/servers/zts/src/test/java/com/yahoo/athenz/zts/store/CloudStoreTest.java index 0240ae56a87..33510a530c0 100644 --- a/servers/zts/src/test/java/com/yahoo/athenz/zts/store/CloudStoreTest.java +++ b/servers/zts/src/test/java/com/yahoo/athenz/zts/store/CloudStoreTest.java @@ -27,8 +27,8 @@ import com.yahoo.rdl.Timestamp; import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.ContentResponse; +import org.eclipse.jetty.client.Request; import org.eclipse.jetty.http.HttpMethod; import org.mockito.Mockito; import org.testng.annotations.Test; diff --git a/servers/zts/src/test/resources/invalid_keystore.jks b/servers/zts/src/test/resources/invalid_keystore.jks new file mode 100644 index 00000000000..f0a52c033f3 --- /dev/null +++ b/servers/zts/src/test/resources/invalid_keystore.jks @@ -0,0 +1 @@ +invalid-keystore \ No newline at end of file diff --git a/syncers/auth_history_syncer/pom.xml b/syncers/auth_history_syncer/pom.xml index c870943a937..2e6e8eccfce 100644 --- a/syncers/auth_history_syncer/pom.xml +++ b/syncers/auth_history_syncer/pom.xml @@ -33,7 +33,7 @@ 0.8593 - 2.2.1 + 2.5.2 1.0.392 4.13.2