diff --git a/pom.xml b/pom.xml index f36ac98..fab527a 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ org.gcube.distribution gcube-bom - 3.0.0-SNAPSHOT + 3.0.1-SNAPSHOT pom import @@ -25,7 +25,6 @@ 8.0.42 - 2.25.1 UTF-8 11 11 @@ -39,7 +38,6 @@ org.reflections reflections - 0.9.10 org.yaml @@ -54,7 +52,7 @@ org.gcube.common health-api - 1.0.0-SNAPSHOT + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) @@ -122,14 +120,6 @@ micrometer-registry-prometheus 1.9.0 - - - org.jboss.shrinkwrap.resolver - shrinkwrap-resolver-depchain - 2.0.0-beta-2 - pom - test - org.apache.tomcat @@ -137,30 +127,6 @@ ${tomcat.version} provided - - org.apache.tomcat.embed - tomcat-embed-core - ${tomcat.version} - test - - - org.glassfish.jersey.core - jersey-client - 2.25.1 - test - - - org.apache.tomcat.embed - tomcat-embed-logging-log4j - ${tomcat.version} - test - - - org.apache.tomcat.embed - tomcat-embed-jasper - ${tomcat.version} - test - junit junit diff --git a/src/main/java/org/gcube/smartgears/Bootstrap.java b/src/main/java/org/gcube/smartgears/Bootstrap.java index 599e1b8..2137f31 100644 --- a/src/main/java/org/gcube/smartgears/Bootstrap.java +++ b/src/main/java/org/gcube/smartgears/Bootstrap.java @@ -44,6 +44,8 @@ public class Bootstrap implements ServletContainerInitializer { public Bootstrap() { + log.info("bootstrap started the container"); + if (smartgearsHasStarted) return; @@ -61,6 +63,8 @@ public class Bootstrap implements ServletContainerInitializer { ApplicationManager appManager = new ApplicationManager(); + log.info("check if is managed @ {}", application.getContextPath()); + //act only on resources if (isResource(application)) { @@ -82,7 +86,7 @@ public class Bootstrap implements ServletContainerInitializer { + " (see cause)", t); } - } + } else log.info("is not managed @ {}", application.getContextPath()); } // helpers diff --git a/src/main/java/org/gcube/smartgears/configuration/AuthorizationProviderConfiguration.java b/src/main/java/org/gcube/smartgears/configuration/AuthorizationProviderConfiguration.java index 01cda29..9f87397 100644 --- a/src/main/java/org/gcube/smartgears/configuration/AuthorizationProviderConfiguration.java +++ b/src/main/java/org/gcube/smartgears/configuration/AuthorizationProviderConfiguration.java @@ -1,16 +1,16 @@ package org.gcube.smartgears.configuration; import org.gcube.common.security.credentials.Credentials; -import org.gcube.common.validator.annotations.NotEmpty; +import org.gcube.common.validator.annotations.IsValid; import org.gcube.common.validator.annotations.NotNull; import org.gcube.smartgears.security.AuthorizationProviderFactory; public class AuthorizationProviderConfiguration { - @NotNull @NotEmpty + @NotNull AuthorizationProviderFactory authProviderFactory; - @NotNull @NotEmpty + @NotNull @IsValid Credentials credentials; public AuthorizationProviderConfiguration(AuthorizationProviderFactory authProviderFactory, diff --git a/src/main/java/org/gcube/smartgears/configuration/container/ContainerConfiguration.java b/src/main/java/org/gcube/smartgears/configuration/container/ContainerConfiguration.java index 128b968..a9a76f3 100644 --- a/src/main/java/org/gcube/smartgears/configuration/container/ContainerConfiguration.java +++ b/src/main/java/org/gcube/smartgears/configuration/container/ContainerConfiguration.java @@ -244,7 +244,7 @@ public class ContainerConfiguration { for (ValidationError error : validator.validate(this)) msgs.add(error.toString()); - + if (!msgs.isEmpty()) throw new IllegalStateException("invalid configuration: "+msgs); diff --git a/src/main/java/org/gcube/smartgears/extensions/RequestExceptionBarrier.java b/src/main/java/org/gcube/smartgears/extensions/RequestExceptionBarrier.java index b419b7b..d80cce9 100644 --- a/src/main/java/org/gcube/smartgears/extensions/RequestExceptionBarrier.java +++ b/src/main/java/org/gcube/smartgears/extensions/RequestExceptionBarrier.java @@ -23,6 +23,7 @@ import org.gcube.smartgears.utils.Utils; */ public class RequestExceptionBarrier implements Filter { + @Override public void init(FilterConfig filterConfig) throws ServletException { } @@ -31,10 +32,8 @@ public class RequestExceptionBarrier implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException { try { - - - chain.doFilter(request, response); + chain.doFilter(request, response); } catch (Throwable t) { diff --git a/src/main/java/org/gcube/smartgears/handlers/AbstractHandler.java b/src/main/java/org/gcube/smartgears/handlers/AbstractHandler.java index 9f260c1..9bb80ff 100644 --- a/src/main/java/org/gcube/smartgears/handlers/AbstractHandler.java +++ b/src/main/java/org/gcube/smartgears/handlers/AbstractHandler.java @@ -21,6 +21,7 @@ public abstract class AbstractHandler { return this.getClass().getCanonicalName().equals(handler.getClass().getCanonicalName()); } + //so far, largely a placeholder for future cross-handler behaviour } diff --git a/src/main/java/org/gcube/smartgears/handlers/application/RequestHandler.java b/src/main/java/org/gcube/smartgears/handlers/application/RequestHandler.java index 95fa9d2..e61e87e 100644 --- a/src/main/java/org/gcube/smartgears/handlers/application/RequestHandler.java +++ b/src/main/java/org/gcube/smartgears/handlers/application/RequestHandler.java @@ -68,5 +68,7 @@ public abstract class RequestHandler extends AbstractHandler implements Applicat */ public void stop() { } + + } diff --git a/src/main/java/org/gcube/smartgears/handlers/application/request/RequestMetrics.java b/src/main/java/org/gcube/smartgears/handlers/application/request/RequestMetrics.java index 0cb9075..8b4f171 100644 --- a/src/main/java/org/gcube/smartgears/handlers/application/request/RequestMetrics.java +++ b/src/main/java/org/gcube/smartgears/handlers/application/request/RequestMetrics.java @@ -41,7 +41,7 @@ public class RequestMetrics extends RequestHandler { Metrics.timer(HTTP_REQUEST_METRICS_NAME, "status", statusCode).record(Duration.ofMillis(System.currentTimeMillis() - startCallThreadLocal.get())); startCallThreadLocal.remove(); }catch(Throwable t) { - log.warn("error getting Metrics",t); + log.warn("error setting Metrics",t); } } diff --git a/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java b/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java index 3232aa5..175ac93 100644 --- a/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java +++ b/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java @@ -191,8 +191,6 @@ public class ApplicationManager { FilterRegistration.Dynamic filter = app.addFilter(name + "-filter-"+mapping.replaceAll("/", ""), requestFilter); - log.trace("filter {} for requestfilter {} in contextPath {} is null ?? {} ",name ,requestFilter, mapping, (filter==null)); - filter.addMappingForUrlPatterns(null, false, mapping); } } diff --git a/src/main/java/org/gcube/smartgears/managers/ContainerManager.java b/src/main/java/org/gcube/smartgears/managers/ContainerManager.java index 8bf1e50..86ba28f 100644 --- a/src/main/java/org/gcube/smartgears/managers/ContainerManager.java +++ b/src/main/java/org/gcube/smartgears/managers/ContainerManager.java @@ -54,8 +54,8 @@ public class ContainerManager { this.context = context; try { - + if (context.configuration().mode()!=Mode.offline) validateContainer(context); @@ -65,18 +65,17 @@ public class ContainerManager { log.trace("managing container lifecycle with {}", handlers); - + startHandlers(handlers); context.lifecycle().moveTo(active); - + return context; - } - catch(RuntimeException e) { + } catch (RuntimeException e) { - log.error("cannot manage container (see cause)",e); + log.error("cannot manage container (see cause)", e); - if (context!=null) + if (context != null) context.lifecycle().moveTo(failed); throw e; @@ -84,12 +83,11 @@ public class ContainerManager { } - private void saveContainerState() { - File file = context.persistenceWriter().file(container_profile_file_path); - try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))){ + File file = context.persistenceWriter().file(container_profile_file_path); + try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) { oos.writeObject(context.id()); - }catch (Exception e) { + } catch (Exception e) { log.error("error serializing cointainer state"); throw new RuntimeException(e); } @@ -97,40 +95,40 @@ public class ContainerManager { } private void validateContainer(ContainerContext context) { - //List tokensToRemove = new ArrayList(); + // List tokensToRemove = new ArrayList(); context.configuration().validate(); Set foundContexts; - + try { foundContexts = context.authorizationProvider().getContexts(); } catch (Exception e) { - log.error("error authorizing container",e); - throw new RuntimeException("error authorizing container, moving the container to failed",e); - } + log.error("error authorizing container", e); + throw new RuntimeException("error authorizing container, moving the container to failed", e); + } - if (foundContexts.isEmpty()){ + if (foundContexts.isEmpty()) { log.error("no valid contexts found, moving the container to failed"); throw new RuntimeException("no valid contexts found, moving the container to failed"); } - + } public void manage(ApplicationContext app) { - app.events().subscribe(this); + app.events().subscribe(this); } - @Observes(value={ApplicationLifecycle.failure,ApplicationLifecycle.stop},kind=Kind.critical) + @Observes(value = { ApplicationLifecycle.failure, ApplicationLifecycle.stop }, kind = Kind.critical) void monitorApplication(ApplicationLifecycle lifecycle) { context.lifecycle().tryMoveTo(ContainerState.partActive); } - @Observes(value=ContextEvents.ADD_CONTEXT_TO_CONTAINER,kind=Kind.critical) + @Observes(value = ContextEvents.ADD_CONTEXT_TO_CONTAINER, kind = Kind.critical) void addContext(String scope) { log.info("adding context {} event send", context); context.events().fire(scope, ProfileEvents.addToContext); } - @Observes(value=ContextEvents.REMOVE_CONTEXT_FROM_CONTAINER,kind=Kind.critical) + @Observes(value = ContextEvents.REMOVE_CONTEXT_FROM_CONTAINER, kind = Kind.critical) void removeContext(String scope) { log.info("removing context {} event send", context); context.events().fire(scope, ProfileEvents.removeFromContext); @@ -145,18 +143,20 @@ public class ContainerManager { stop(false); } - /** * Stops container management on remote request or container shutdown. * */ public void stop(boolean shutdown) { - //two cases: stop-on-shutdown and stop-on-request, some listeners will be selective about this, + // two cases: stop-on-shutdown and stop-on-request, some listeners will be + // selective about this, - //shutdown is triggered by probe app, which is notified among other apps - //if other app have been already notified, the container may already be part-active. - //apps still to notify will listen only on stop, hence won't react to this but will go down when their turn arrives. + // shutdown is triggered by probe app, which is notified among other apps + // if other app have been already notified, the container may already be + // part-active. + // apps still to notify will listen only on stop, hence won't react to this but + // will go down when their turn arrives. if (context == null) return; @@ -165,26 +165,23 @@ public class ContainerManager { try { - context.lifecycle().tryMoveTo(shutdown?down:stopped); - + context.lifecycle().tryMoveTo(shutdown ? down : stopped); + stopHandlers(); - //no further reactions + // no further reactions log.info("stopping container events"); context.events().stop(); Utils.scheduledServicePool.shutdownNow(); - } - catch (RuntimeException e) { + } catch (RuntimeException e) { log.warn("cannot stop container management (see cause)", e); } } - - - //helpers + // helpers private void startHandlers(List handlers) { @@ -201,7 +198,6 @@ public class ContainerManager { } } - private void stopHandlers() { if (pipeline == null) @@ -214,46 +210,32 @@ public class ContainerManager { returnPipeline.forward(new ContainerLifecycleEvent.Stop(context)); } -/* - private void loadKeyForToken(List tokens) { - String initialToken = SecurityTokenProvider.instance.get(); - - //TODO: change this - String filePath = "/tmp/keys"; - File PathDirs = new File(filePath+"/"); - PathDirs.mkdirs(); - try{ - for (String token : tokens) { - try{ - SecurityTokenProvider.instance.set(token); - File key = authProvider.getSymmKey(filePath); - log.trace("loading key {} file name ",key.getAbsolutePath()); - log.trace("loaded key {} file name ",key.getAbsolutePath()); - }catch(Exception e){ - log.warn("error loading key for token {}", token, e); - } - } - loadFileIntoClasspath(PathDirs); - }finally{ - SecurityTokenProvider.instance.set(initialToken); - } - } - - - private void loadFileIntoClasspath(File file){ - try { - URL url = file.toURI().toURL(); - - ClassLoader currentClassloader = Thread.currentThread().getContextClassLoader().getParent()==null? - Thread.currentThread().getContextClassLoader() : Thread.currentThread().getContextClassLoader().getParent(); - - URLClassLoader classLoader = (URLClassLoader)currentClassloader; - Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - method.invoke(classLoader, url); - } catch (Exception ex) { - log.error("error loading file into classpath",ex); - } - } - */ + /* + * private void loadKeyForToken(List tokens) { String initialToken = + * SecurityTokenProvider.instance.get(); + * + * //TODO: change this String filePath = "/tmp/keys"; File PathDirs = new + * File(filePath+"/"); PathDirs.mkdirs(); try{ for (String token : tokens) { + * try{ SecurityTokenProvider.instance.set(token); File key = + * authProvider.getSymmKey(filePath); + * log.trace("loading key {} file name ",key.getAbsolutePath()); + * log.trace("loaded key {} file name ",key.getAbsolutePath()); }catch(Exception + * e){ log.warn("error loading key for token {}", token, e); } } + * loadFileIntoClasspath(PathDirs); }finally{ + * SecurityTokenProvider.instance.set(initialToken); } } + * + * + * private void loadFileIntoClasspath(File file){ try { URL url = + * file.toURI().toURL(); + * + * ClassLoader currentClassloader = + * Thread.currentThread().getContextClassLoader().getParent()==null? + * Thread.currentThread().getContextClassLoader() : + * Thread.currentThread().getContextClassLoader().getParent(); + * + * URLClassLoader classLoader = (URLClassLoader)currentClassloader; Method + * method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + * method.setAccessible(true); method.invoke(classLoader, url); } catch + * (Exception ex) { log.error("error loading file into classpath",ex); } } + */ } diff --git a/src/main/java/org/gcube/smartgears/managers/RequestManager.java b/src/main/java/org/gcube/smartgears/managers/RequestManager.java index cf28d8b..4e0414d 100644 --- a/src/main/java/org/gcube/smartgears/managers/RequestManager.java +++ b/src/main/java/org/gcube/smartgears/managers/RequestManager.java @@ -79,7 +79,7 @@ public class RequestManager implements Filter { ApplicationPipeline pipeline = new ApplicationPipeline(filterHandlers); - log.trace("filtered handler for this call are {}", filterHandlers); + log.debug("filtered handler for this call are {}", filterHandlers); // create a per-request context with temporary properties ApplicationContext ctx = new DefaultApplicationContext(context); @@ -133,21 +133,26 @@ public class RequestManager implements Filter { path += request.getPathInfo() ==null?"":request.getPathInfo(); - - log.debug("check wich handler should be excluded {}", path); + log.debug("check which handler should be excluded {}", path); if (!context.configuration().excludes().isEmpty()) { + log.debug("excludes are not empty"); for (GCubeExclude exclude : context.configuration().excludes()){ String excludePath= exclude.getPath(); - log.trace("exclude is {}",exclude); + log.debug("exclude is {}",exclude); if ((WILDCARD).equals(excludePath) || (excludePath.endsWith(WILDCARD) && path!=null && path.startsWith(excludePath.substring(0,excludePath.length()-2))) || excludePath.equals(path) || (path.endsWith("/") && excludePath.equals(path.substring(0, path.length()-1))) ){ - //ALL handler are filtered except for unfiltrable - if (exclude.getHandlers().isEmpty()) return handlersToFilter.stream() + //ALL handler are filtered except for unfilterable + if (exclude.getHandlers().isEmpty()) { + List unfilterables = handlersToFilter.stream() + .filter(RequestHandler::isUnfiltrable).collect(Collectors.toList()); + log.debug("exclude handler is empty so unfilterable handlers are {}",unfilterables); + return handlersToFilter.stream() .filter(RequestHandler::isUnfiltrable).collect(Collectors.toList()); - + } + List filteredHandlers = new ArrayList<>(); for (RequestHandler rh : handlersToFilter) if (rh.isUnfiltrable() || !exclude.getHandlers().contains(rh.getName())) @@ -178,7 +183,7 @@ public class RequestManager implements Filter { } return new ArrayList<>(); } - + log.debug("returning original handlers"); return handlersToFilter; } diff --git a/src/main/java/org/gcube/smartgears/provider/DefaultProvider.java b/src/main/java/org/gcube/smartgears/provider/DefaultProvider.java index 1308cc8..8cacaa4 100644 --- a/src/main/java/org/gcube/smartgears/provider/DefaultProvider.java +++ b/src/main/java/org/gcube/smartgears/provider/DefaultProvider.java @@ -155,7 +155,7 @@ public class DefaultProvider implements Provider { } ApplicationHandlers defaultHandlers = binder.bindHandlers(currentClassLoader); - + return defaultHandlers; } catch (RuntimeException e) { diff --git a/src/main/java/org/gcube/smartgears/security/defaults/DefaultAuthorizationProviderFactory.java b/src/main/java/org/gcube/smartgears/security/defaults/DefaultAuthorizationProviderFactory.java index e9d6cb3..87b34c9 100644 --- a/src/main/java/org/gcube/smartgears/security/defaults/DefaultAuthorizationProviderFactory.java +++ b/src/main/java/org/gcube/smartgears/security/defaults/DefaultAuthorizationProviderFactory.java @@ -1,6 +1,10 @@ package org.gcube.smartgears.security.defaults; +import java.util.List; + import org.gcube.common.security.credentials.Credentials; +import org.gcube.common.validator.ValidationError; +import org.gcube.common.validator.ValidatorFactory; import org.gcube.common.validator.annotations.NotEmpty; import org.gcube.smartgears.security.AuthorizationProviderFactory; import org.gcube.smartgears.security.SimpleCredentials; @@ -14,6 +18,9 @@ public class DefaultAuthorizationProviderFactory implements AuthorizationProvide public DefaultAuthorizationProvider connect(Credentials credentials) { if (!SimpleCredentials.class.isInstance(credentials)) throw new IllegalArgumentException("invalid credential type passed"); + List errors = ValidatorFactory.validator().validate(credentials); + if (!errors.isEmpty()) + throw new IllegalArgumentException(String.format("invalid credential: %s", errors)); if (this.endpoint == null || this.endpoint.isEmpty()) throw new IllegalArgumentException("invalid enpoint passed"); return new DefaultAuthorizationProvider((SimpleCredentials)credentials, this.endpoint);