diff --git a/.travis.yml b/.travis.yml index b5388731..6febb6d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: java jdk: -- oraclejdk7 +- oraclejdk8 sudo: false install: ./installViaTravis.sh script: ./buildViaTravis.sh diff --git a/buildViaTravis.sh b/buildViaTravis.sh index c83bf311..a4db38eb 100755 --- a/buildViaTravis.sh +++ b/buildViaTravis.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then echo -e "Build Pull Request #$TRAVIS_PULL_REQUEST => Branch [$TRAVIS_BRANCH]" - ./gradlew build --info + ./gradlew build --stacktrace --info elif [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_TAG" == "" ]; then echo -e 'Build Branch with Snapshot => Branch ['$TRAVIS_BRANCH']' ./gradlew -Prelease.travisci=true -PbintrayUser="${bintrayUser}" -PbintrayKey="${bintrayKey}" -PsonatypeUsername="${sonatypeUsername}" -PsonatypePassword="${sonatypePassword}" build snapshot diff --git a/gradle.properties b/gradle.properties index f9a6ae99..4a7a0c3d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,8 +16,8 @@ org.gradle.daemon=true rxnetty_version=0.4.7 -jersey_version=1.18.1 -governator_version=1.9.3 -pytheas_version=1.25 +jersey_version=1.19.1 +governator_version=1.14.2 +pytheas_version=1.29.0 apache_httpclient_version=4.2.1 eureka_version=1.1.151 diff --git a/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/build.gradle b/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/build.gradle index 071942fb..689d06f0 100644 --- a/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/build.gradle +++ b/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/build.gradle @@ -21,8 +21,9 @@ tasks.withType(Javadoc).each { dependencies { compile ('com.netflix.karyon:karyon-eureka:1.+') - testRuntime ('com.sun.jersey:jersey-core:1.18.1') { force = true } compile project(':karyon2-admin') + + testCompile 'org.slf4j:slf4j-log4j12:1.7.2' } eclipse { diff --git a/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/java/netflix/adminresources/HealthCheckResourceTest.java b/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/java/netflix/adminresources/HealthCheckResourceTest.java index a26ec21d..b0bb3acd 100644 --- a/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/java/netflix/adminresources/HealthCheckResourceTest.java +++ b/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/java/netflix/adminresources/HealthCheckResourceTest.java @@ -6,21 +6,22 @@ import com.netflix.config.ConfigurationManager; import com.netflix.karyon.server.eureka.HealthCheckInvocationStrategy; import com.netflix.karyon.server.eureka.SyncHealthCheckInvocationStrategy; -import netflix.admin.AdminConfigImpl; import com.netflix.karyon.spi.HealthCheckHandler; + import org.apache.commons.configuration.AbstractConfiguration; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import javax.ws.rs.core.Response; -import java.lang.reflect.Field; import static org.junit.Assert.assertEquals; +import netflix.admin.AdminConfigImpl; public class HealthCheckResourceTest { private AdminResourcesContainer container; @@ -67,8 +68,6 @@ private void checkHealth(HealthCheckHandler healthCheckHandler, int respStatus) private AdminResourcesContainer buildAdminResourcesContainer(final HealthCheckHandler healthCheckHandler) throws Exception { - AdminResourcesContainer container = new AdminResourcesContainer(); - final Field injectorField = AdminResourcesContainer.class.getDeclaredField("appInjector"); final Injector appInjector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { @@ -76,9 +75,7 @@ protected void configure() { bind(HealthCheckInvocationStrategy.class).to(SyncHealthCheckInvocationStrategy.class); } }); - injectorField.setAccessible(true); - injectorField.set(container, appInjector); - return container; + return appInjector.getInstance(AdminResourcesContainer.class); } private HealthCheckHandler goodHealthHandler() { diff --git a/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/resources/log4j.properties b/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/resources/log4j.properties new file mode 100644 index 00000000..9e25ad93 --- /dev/null +++ b/karyon2-admin-plugins/karyon-admin-healthcheck-plugin/src/test/resources/log4j.properties @@ -0,0 +1,22 @@ +# +# Copyright 2012 Netflix, Inc. +# +# Licensed 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. +# + +log4j.rootLogger=INFO, console + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d %-5p %c{1}:%L %x %m [%t]%n +log4j.logger.com.sun.jersey=TRACE \ No newline at end of file diff --git a/karyon2-admin/build.gradle b/karyon2-admin/build.gradle index 2b1b4a56..ed2a74a5 100644 --- a/karyon2-admin/build.gradle +++ b/karyon2-admin/build.gradle @@ -20,11 +20,15 @@ dependencies { compile 'javax.ws.rs:jsr311-api:1.1.1' compile 'javax.servlet:javax.servlet-api:3.0.1' compile 'org.mortbay.jetty:jetty:6.1.26' + compile 'com.google.inject.extensions:guice-servlet:4.1.0' compile 'com.sun.jersey.contribs:jersey-guice:${jersey_version}' compile "com.sun.jersey:jersey-servlet:${jersey_version}" compile "com.sun.jersey:jersey-server:${jersey_version}" compile "com.netflix.pytheas:pytheas-core:${pytheas_version}" compile "com.sun.jersey:jersey-core:${jersey_version}" + compile "com.sun.jersey:jersey-servlet:${jersey_version}" + compile "com.sun.jersey:jersey-server:${jersey_version}" + compile "com.sun.jersey:jersey-json:${jersey_version}" runtime 'org.codehaus.jackson:jackson-mapper-asl:1.9.11' testCompile "org.apache.httpcomponents:httpclient:${apache_httpclient_version}" diff --git a/karyon2-admin/src/main/java/netflix/admin/AdminFreemarkerTemplateProvider.java b/karyon2-admin/src/main/java/netflix/admin/AdminFreemarkerTemplateProvider.java index 63600a63..d29b3b43 100644 --- a/karyon2-admin/src/main/java/netflix/admin/AdminFreemarkerTemplateProvider.java +++ b/karyon2-admin/src/main/java/netflix/admin/AdminFreemarkerTemplateProvider.java @@ -22,22 +22,10 @@ import com.netflix.explorers.context.RequestContext; import com.netflix.explorers.providers.ToJsonMethod; import com.sun.jersey.api.view.Viewable; -import freemarker.cache.ClassTemplateLoader; -import freemarker.cache.MultiTemplateLoader; -import freemarker.cache.TemplateLoader; -import freemarker.template.Configuration; -import freemarker.template.TemplateModelException; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; -import javax.ws.rs.ext.MessageBodyWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -48,6 +36,21 @@ import java.util.HashMap; import java.util.Map; +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.MessageBodyWriter; + +import freemarker.cache.ClassTemplateLoader; +import freemarker.cache.MultiTemplateLoader; +import freemarker.cache.TemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.TemplateModelException; + public class AdminFreemarkerTemplateProvider implements MessageBodyWriter { private static final Logger LOG = LoggerFactory.getLogger(AdminFreemarkerTemplateProvider.class); private static final String ADMIN_CONSOLE_LAYOUT = "bootstrap"; diff --git a/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesContainer.java b/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesContainer.java index dba29c52..2d2ef48f 100644 --- a/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesContainer.java +++ b/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesContainer.java @@ -16,28 +16,41 @@ package netflix.adminresources; -import com.google.inject.*; +import com.google.inject.AbstractModule; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.Singleton; +import com.google.inject.Stage; import com.netflix.governator.guice.LifecycleInjector; import com.netflix.governator.lifecycle.LifecycleManager; -import netflix.admin.AdminConfigImpl; -import netflix.admin.AdminContainerConfig; +import com.sun.jersey.guice.JerseyServletModule; + import org.mortbay.jetty.Connector; import org.mortbay.jetty.Handler; import org.mortbay.jetty.Server; import org.mortbay.jetty.handler.HandlerCollection; -import org.mortbay.jetty.servlet.*; +import org.mortbay.jetty.servlet.Context; +import org.mortbay.jetty.servlet.DefaultServlet; +import org.mortbay.jetty.servlet.FilterHolder; +import org.mortbay.jetty.servlet.ServletHolder; +import org.mortbay.jetty.servlet.SessionHandler; import org.mortbay.thread.QueuedThreadPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.servlet.Filter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.servlet.Filter; + +import netflix.admin.AdminConfigImpl; +import netflix.admin.AdminContainerConfig; + /** * This class starts an embedded jetty server, listening at port specified by property * {@link netflix.admin.AdminContainerConfig#listenPort()} and defaulting to @@ -126,6 +139,7 @@ public void init() throws Exception { AdminResourcesFilter arfTemplatesResources = adminResourceInjector.getInstance(AdminResourcesFilter.class); arfTemplatesResources.setPackages(adminContainerConfig.jerseyViewableResourcePkgList()); + logger.info("Admin templates context : {}", adminContainerConfig.templateResourceContext()); final Context adminTemplatesResHandler = new Context(); adminTemplatesResHandler.setContextPath(adminContainerConfig.templateResourceContext()); adminTemplatesResHandler.setSessionHandler(new SessionHandler()); @@ -140,8 +154,10 @@ public void init() throws Exception { AdminResourcesFilter arfDataResources = adminResourceInjector.getInstance(AdminResourcesFilter.class); arfDataResources.setPackages(jerseyPkgListForAjaxResources); + logger.info("Admin resources context : {}", adminContainerConfig.ajaxDataResourceContext()); final Context adminDataResHandler = new Context(); adminDataResHandler.setContextPath(adminContainerConfig.ajaxDataResourceContext()); + adminDataResHandler.addFilter(LoggingFilter.class, "/*", Handler.DEFAULT); adminDataResHandler.addFilter(new FilterHolder(adminResourceInjector.getInstance(RedirectFilter.class)), "/*", Handler.DEFAULT); applyAdditionalFilters(adminDataResHandler, additionaFilters); adminDataResHandler.addFilter(new FilterHolder(arfDataResources), "/*", Handler.DEFAULT); @@ -159,6 +175,8 @@ public void init() throws Exception { final Connector connector = server.getConnectors()[0]; serverPort = connector.getLocalPort(); + + logger.info("jetty started on port {}", serverPort); } } catch (Exception e) { logger.error("Exception in building AdminResourcesContainer ", e); @@ -190,6 +208,7 @@ private Module getAdditionalBindings() { @Override protected void configure() { bind(AdminResourcesFilter.class); + if (! shouldShareResourcesWithParentInjector()) { bind(AdminPageRegistry.class).toInstance(adminPageRegistry); bind(AdminContainerConfig.class).toInstance(adminContainerConfig); @@ -212,6 +231,10 @@ private List buildAdminPluginsGuiceModules() { if (adminPageRegistry != null) { final Collection allPages = adminPageRegistry.getAllPages(); for (AdminPageInfo adminPlugin : allPages) { + logger.info("Adding admin page {}: jersey={} modules{}", + adminPlugin.getName(), + adminPlugin.getJerseyResourcePackageList(), + adminPlugin.getGuiceModules()); final List guiceModuleList = adminPlugin.getGuiceModules(); if (guiceModuleList != null && !guiceModuleList.isEmpty()) { guiceModules.addAll(adminPlugin.getGuiceModules()); diff --git a/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesFilter.java b/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesFilter.java index 1793f3d4..f325556f 100644 --- a/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesFilter.java +++ b/karyon2-admin/src/main/java/netflix/adminresources/AdminResourcesFilter.java @@ -3,21 +3,24 @@ import com.google.common.collect.Maps; import com.google.inject.Injector; import com.netflix.explorers.providers.FreemarkerTemplateProvider; +import com.netflix.explorers.providers.WebApplicationExceptionMapper; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.api.core.ResourceConfig; import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; import com.sun.jersey.spi.container.servlet.WebConfig; -import netflix.admin.AdminFreemarkerTemplateProvider; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Set; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URI; -import java.util.Map; -import java.util.Set; + +import netflix.admin.AdminFreemarkerTemplateProvider; /** * This class is a minimal simulation of GuiceFilter. Due to the number of @@ -70,6 +73,8 @@ public int service(URI baseUri, URI requestUri, HttpServletRequest request, Http protected ResourceConfig getDefaultResourceConfig(Map props, WebConfig webConfig) throws ServletException { props.put(PackagesResourceConfig.PROPERTY_PACKAGES, packages); + props.put(ResourceConfig.FEATURE_DISABLE_WADL, "false"); + return new PackagesResourceConfig(props) { @Override public Set> getProviderClasses() { @@ -77,6 +82,7 @@ public Set> getProviderClasses() { // remove conflicting provider if present providers.remove(FreemarkerTemplateProvider.class); providers.add(AdminFreemarkerTemplateProvider.class); + providers.add(WebApplicationExceptionMapper.class); return providers; } };