diff --git a/.classpath b/.classpath index 50217e7..a9245a1 100644 --- a/.classpath +++ b/.classpath @@ -27,7 +27,7 @@ - + diff --git a/distro/LICENSE b/distro/LICENSE index 3695e26..cdf50bd 100644 --- a/distro/LICENSE +++ b/distro/LICENSE @@ -1 +1,4 @@ -${gcube.license} +gCube System - License +------------------------------------------------------------ + +${gcube.license} \ No newline at end of file diff --git a/distro/descriptor.xml b/distro/descriptor.xml index e395580..ba2c192 100644 --- a/distro/descriptor.xml +++ b/distro/descriptor.xml @@ -10,13 +10,13 @@ ${distroDirectory} - / + ${file.separator} true README LICENSE changelog.xml - profile.xml + profile.xml 755 true @@ -24,9 +24,8 @@ - target/${build.finalName}.${project.packaging} - /${artifactId} + target${file.separator}${build.finalName}.${project.packaging} + ${file.separator}${artifactId} - \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml index 91c49e4..c510260 100644 --- a/distro/profile.xml +++ b/distro/profile.xml @@ -1,14 +1,16 @@ - + + Service ${description} - Common + ${serviceClass} ${artifactId} 1.0.0 + ${description} ${artifactId} ${version} @@ -16,8 +18,9 @@ ${artifactId} ${version} + Library - ${build.finalName}.jar + ${build.finalName}.${project.packaging} diff --git a/pom.xml b/pom.xml index c9aec40..44ea0ba 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.gcube.core common-smartgears - 2.1.5-SNAPSHOT + 2.1.6-SNAPSHOT SmartGears @@ -149,7 +149,7 @@ ch.qos.logback logback-classic - 1.0.13 + 1.2.3 runtime diff --git a/src/main/java/org/gcube/smartgears/Constants.java b/src/main/java/org/gcube/smartgears/Constants.java index acb233b..acb3790 100644 --- a/src/main/java/org/gcube/smartgears/Constants.java +++ b/src/main/java/org/gcube/smartgears/Constants.java @@ -84,7 +84,7 @@ public class Constants { /** * The wildcard exclude directive. */ - public static final String EXCLUDE_ALL = "*"; + public static final String WILDCARD = "*"; /** diff --git a/src/main/java/org/gcube/smartgears/configuration/application/ApplicationConfiguration.java b/src/main/java/org/gcube/smartgears/configuration/application/ApplicationConfiguration.java index b8323c4..05d7e75 100644 --- a/src/main/java/org/gcube/smartgears/configuration/application/ApplicationConfiguration.java +++ b/src/main/java/org/gcube/smartgears/configuration/application/ApplicationConfiguration.java @@ -138,6 +138,12 @@ public interface ApplicationConfiguration { */ Set excludes(); + /** + * Returns a set of request paths that should be subjected to request management. + * @return the set of exclude paths. + */ + Set includes(); + /** * Sets the persistence manager of the application. @@ -162,6 +168,8 @@ public interface ApplicationConfiguration { void merge(ApplicationConfiguration config); ApplicationConfiguration excludes(Exclude ... excludes); + + ApplicationConfiguration includes(Include ... includes); diff --git a/src/main/java/org/gcube/smartgears/configuration/application/BridgedApplicationConfiguration.java b/src/main/java/org/gcube/smartgears/configuration/application/BridgedApplicationConfiguration.java index f1182b9..6140b29 100644 --- a/src/main/java/org/gcube/smartgears/configuration/application/BridgedApplicationConfiguration.java +++ b/src/main/java/org/gcube/smartgears/configuration/application/BridgedApplicationConfiguration.java @@ -120,6 +120,11 @@ public class BridgedApplicationConfiguration implements ApplicationConfiguration return application.excludes(); } + @Override + public Set includes() { + return application.includes(); + } + @Override public void merge(ApplicationConfiguration config) { application.merge(config); @@ -159,4 +164,11 @@ public class BridgedApplicationConfiguration implements ApplicationConfiguration public ApplicationConfiguration excludes(Exclude ... excludes) { return application.excludes(excludes); } + + @Override + public ApplicationConfiguration includes(Include... includes) { + return application.includes(includes); + } + + } diff --git a/src/main/java/org/gcube/smartgears/configuration/application/DefaultApplicationConfiguration.java b/src/main/java/org/gcube/smartgears/configuration/application/DefaultApplicationConfiguration.java index 3c2e8fb..fb89df4 100644 --- a/src/main/java/org/gcube/smartgears/configuration/application/DefaultApplicationConfiguration.java +++ b/src/main/java/org/gcube/smartgears/configuration/application/DefaultApplicationConfiguration.java @@ -67,6 +67,9 @@ public class DefaultApplicationConfiguration implements ApplicationConfiguration @XmlElementRef Set excludes= new LinkedHashSet(); + + @XmlElementRef + Set includes= new LinkedHashSet(); @XmlElementRef(type=DefaultPersistence.class) @NotNull @IsValid @@ -77,6 +80,11 @@ public class DefaultApplicationConfiguration implements ApplicationConfiguration return excludes; } + @Override + public Set includes() { + return includes; + } + public DefaultApplicationConfiguration() {} @Override @@ -111,6 +119,12 @@ public class DefaultApplicationConfiguration implements ApplicationConfiguration return this; } + @Override + public ApplicationConfiguration includes(Include... includes) { + this.includes=new HashSet(Arrays.asList(includes)); + return this; + } + @Override public ApplicationConfiguration name(String name) { this.name=name; @@ -207,6 +221,9 @@ public class DefaultApplicationConfiguration implements ApplicationConfiguration for (ValidationError error : validator.validate(this)) msgs.add(error.toString()); + if (!this.excludes().isEmpty() && !this.includes().isEmpty()) + msgs.add("exclude tags and includes tags are mutually exclusive"); + if (!msgs.isEmpty()) throw new IllegalStateException("invalid configuration: "+msgs); @@ -309,4 +326,6 @@ public class DefaultApplicationConfiguration implements ApplicationConfiguration return true; } + + } \ No newline at end of file diff --git a/src/main/java/org/gcube/smartgears/configuration/application/Include.java b/src/main/java/org/gcube/smartgears/configuration/application/Include.java new file mode 100644 index 0000000..e8486c7 --- /dev/null +++ b/src/main/java/org/gcube/smartgears/configuration/application/Include.java @@ -0,0 +1,79 @@ +package org.gcube.smartgears.configuration.application; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlValue; + +@XmlRootElement(name="include") +@XmlAccessorType(XmlAccessType.FIELD) +public class Include { + + @XmlAttribute(name="handlers") + private List handlers = new ArrayList(); + + @XmlValue + private String path; + + public List getHandlers() { + return handlers; + } + + public String getPath() { + return path; + } + + protected Include() {} + + public Include(String path) { + super(); + this.path = path; + } + + public Include(List handlers, String path) { + super(); + this.handlers = handlers; + this.path = path; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((path == null) ? 0 : path.hashCode()); + return result; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Include other = (Include) obj; + if (handlers == null) { + if (other.handlers != null) + return false; + } else if (!handlers.equals(other.handlers)) + return false; + if (path == null) { + if (other.path != null) + return false; + } else if (!path.equals(other.path)) + return false; + return true; + } + + @Override + public String toString() { + return "Include [handlers=" + handlers + ", path=" + path + "]"; + } + + } \ No newline at end of file diff --git a/src/main/java/org/gcube/smartgears/handlers/container/lifecycle/AccountingManager.java b/src/main/java/org/gcube/smartgears/handlers/container/lifecycle/AccountingManager.java index 75f0169..73f6802 100644 --- a/src/main/java/org/gcube/smartgears/handlers/container/lifecycle/AccountingManager.java +++ b/src/main/java/org/gcube/smartgears/handlers/container/lifecycle/AccountingManager.java @@ -5,8 +5,6 @@ package org.gcube.smartgears.handlers.container.lifecycle; import static org.gcube.smartgears.Constants.accounting_management; -import java.util.concurrent.TimeUnit; - import javax.xml.bind.annotation.XmlRootElement; import org.gcube.accounting.persistence.AccountingPersistenceFactory; @@ -26,7 +24,7 @@ public class AccountingManager extends ContainerHandler { @Override public void onStop(ContainerLifecycleEvent.Stop e) { logger.trace("Going to flush accounting data"); - AccountingPersistenceFactory.shutDown(1000, TimeUnit.MILLISECONDS); + AccountingPersistenceFactory.shutDown(); } @Override diff --git a/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java b/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java index 0d8dec5..b2e1aa0 100644 --- a/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java +++ b/src/main/java/org/gcube/smartgears/managers/ApplicationManager.java @@ -77,7 +77,7 @@ public class ApplicationManager { context.configuration().validate(); - + if (context.configuration().secure() && container.configuration().securePort()==null) throw new IllegalStateException( @@ -128,11 +128,14 @@ public class ApplicationManager { return context; } catch (RuntimeException e) { + + - log.error("error starting application {} ", context.name(),e); - - if (context != null) + if (context != null) { + log.error("error starting application {}",context.name(), e); context.lifecycle().moveTo(failed); + } else + log.error("error starting application with context not initialized",e ); throw e; } @@ -240,9 +243,12 @@ public class ApplicationManager { extension.init(context); - //register excludes - context.configuration().excludes().addAll(extension.excludes()); - + + if (context.configuration().includes().isEmpty()) { + //register excludes for extension in case of includes they are excluded by default + context.configuration().excludes().addAll(extension.excludes()); + } + String mapping = extension.mapping(); application.addServlet(context.configuration().name() + "-" + extension.name(), extension) diff --git a/src/main/java/org/gcube/smartgears/managers/RequestManager.java b/src/main/java/org/gcube/smartgears/managers/RequestManager.java index 4f239c7..ec14e99 100644 --- a/src/main/java/org/gcube/smartgears/managers/RequestManager.java +++ b/src/main/java/org/gcube/smartgears/managers/RequestManager.java @@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.gcube.smartgears.configuration.application.Exclude; +import org.gcube.smartgears.configuration.application.Include; import org.gcube.smartgears.context.application.ApplicationContext; import org.gcube.smartgears.context.application.DefaultApplicationContext; import org.gcube.smartgears.handlers.application.ApplicationPipeline; @@ -63,20 +64,20 @@ public class RequestManager implements Filter { HttpServletRequest httprequest = (HttpServletRequest) request; HttpServletResponse httpresponse = (HttpServletResponse) response; - List filterHandlers = getPipelineWithExcluded(httprequest, handlers); - + List filterHandlers = getPipelineHandlers(httprequest, handlers); + if (filterHandlers.isEmpty()){ - + log.trace("filtered handlers are empty"); - + chain.doFilter(request, response); }else { - + ApplicationPipeline pipeline = new ApplicationPipeline(filterHandlers); - + log.trace("filtered handler for this call are {}", filterHandlers); - + // create a per-request context with temporary properties ApplicationContext ctx = new DefaultApplicationContext(context); @@ -112,44 +113,66 @@ public class RequestManager implements Filter { } } - private List getPipelineWithExcluded( + private List getPipelineHandlers( HttpServletRequest request, List handlersToFilter) { - + String query = request.getQueryString(); - + log.debug("servletPath is {} and pathInfo is {}",request.getServletPath(), request.getPathInfo()); if ("wsdl".equals(query) || "wsdl=1".equals(query)) return Collections.emptyList(); - + String path = request.getServletPath()==null?"":request.getServletPath(); - + path += request.getPathInfo() ==null?"":request.getPathInfo(); - - + + log.debug("check wich handler should be excluded {}", path); - - for (Exclude exclude : context.configuration().excludes()){ - String excludePath= exclude.getPath(); - log.trace("exclude is {}",exclude); - if ( - (EXCLUDE_ALL).equals(excludePath) || - (excludePath.endsWith(EXCLUDE_ALL) && 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 - if (exclude.getHandlers().isEmpty()) return Collections.emptyList(); - - List filteredHandlers = new ArrayList<>(); - for (RequestHandler rh : handlersToFilter){ - if (!exclude.getHandlers().contains(rh.getName())) - filteredHandlers.add(rh); + + if (!context.configuration().excludes().isEmpty()) { + for (Exclude exclude : context.configuration().excludes()){ + String excludePath= exclude.getPath(); + log.trace("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 + if (exclude.getHandlers().isEmpty()) return Collections.emptyList(); + + List filteredHandlers = new ArrayList<>(); + for (RequestHandler rh : handlersToFilter){ + if (!exclude.getHandlers().contains(rh.getName())) + filteredHandlers.add(rh); + } + return filteredHandlers; } - return filteredHandlers; } - } + } else if (!context.configuration().includes().isEmpty()) { + for (Include include : context.configuration().includes()){ + String includePath= include.getPath(); + log.trace("include is {}",include); + if ( + (WILDCARD).equals(includePath) || + (includePath.endsWith(WILDCARD) && path!=null && path.startsWith(includePath.substring(0,includePath.length()-2))) || + includePath.equals(path) || (path.endsWith("/") && includePath.equals(path.substring(0, path.length()-1))) + ){ + //ALL handler are used + if (include.getHandlers().isEmpty()) return handlersToFilter; + + List filteredHandlers = new ArrayList<>(); + for (RequestHandler rh : handlersToFilter){ + if (include.getHandlers().contains(rh.getName())) + filteredHandlers.add(rh); + } + return filteredHandlers; + } + } + return new ArrayList<>(); + } - //in case no path is recognized in excludes it return all handlers return handlersToFilter; } @@ -186,23 +209,23 @@ public class RequestManager implements Filter { } // helpers -/* + /* private boolean shouldExcludeRequest(HttpServletRequest request) { String query = request.getQueryString(); - + log.debug("servletPath is {} and pathInfo is {}",request.getServletPath(), request.getPathInfo()); if ("wsdl".equals(query) || "wsdl=1".equals(query)) return true; - + String path = request.getServletPath()==null?"":request.getServletPath(); - + path += request.getPathInfo() ==null?"":request.getPathInfo(); - - + + log.debug("check if should exclude call with path {}", path); - + for (Exclude exclude : context.configuration().excludes()){ if (!exclude.getHandlers().isEmpty()) continue; String excludePath= exclude.getPath(); diff --git a/src/test/java/app/SomeApp.java b/src/test/java/app/SomeApp.java index 4e25724..edc311d 100644 --- a/src/test/java/app/SomeApp.java +++ b/src/test/java/app/SomeApp.java @@ -16,7 +16,6 @@ import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import org.apache.commons.io.FileUtils; import org.apache.tomcat.util.scan.StandardJarScanner; -import org.gcube.informationsystem.publisher.RegistryPublisher; import org.gcube.informationsystem.publisher.ScopedPublisher; import org.gcube.smartgears.Constants; import org.gcube.smartgears.configuration.Mode; @@ -35,11 +34,11 @@ import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.impl.base.path.BasicPath; +import com.sun.jersey.api.client.ClientResponse; + import utils.TestProvider; import utils.TestUtils; -import com.sun.jersey.api.client.ClientResponse; - /** * Simulates a single-servlet application to be transformed into a gCube resource. *

diff --git a/src/test/java/test/application/CallValidationTest.java b/src/test/java/test/application/CallValidationTest.java index e44f7e1..a980908 100644 --- a/src/test/java/test/application/CallValidationTest.java +++ b/src/test/java/test/application/CallValidationTest.java @@ -133,7 +133,7 @@ public class CallValidationTest { SomeApp app = new SomeApp(); - app.configuration().excludes().add(new Exclude(Constants.EXCLUDE_ALL)); + app.configuration().excludes().add(new Exclude(Constants.WILDCARD)); app.handlers().set(new ProfileManager()).set(new RequestValidator()); @@ -160,7 +160,7 @@ public class CallValidationTest { SomeApp app = new SomeApp(); - app.configuration().excludes().add(new Exclude("/path"+Constants.EXCLUDE_ALL)); + app.configuration().excludes().add(new Exclude("/path"+Constants.WILDCARD)); app.handlers().set(new ProfileManager()).set(new RequestValidator()); diff --git a/src/test/java/test/application/ConfigurationTest.java b/src/test/java/test/application/ConfigurationTest.java index 248f756..a444ccf 100644 --- a/src/test/java/test/application/ConfigurationTest.java +++ b/src/test/java/test/application/ConfigurationTest.java @@ -12,6 +12,7 @@ import org.gcube.smartgears.configuration.application.ApplicationConfigurationBi import org.gcube.smartgears.configuration.application.ApplicationExtensions; import org.gcube.smartgears.configuration.application.DefaultApplicationConfiguration; import org.gcube.smartgears.configuration.application.Exclude; +import org.gcube.smartgears.configuration.application.Include; import org.gcube.smartgears.extensions.ApplicationExtension; import org.gcube.smartgears.persistence.DefaultPersistence; import org.junit.Test; @@ -28,7 +29,7 @@ public class ConfigurationTest { "desc" + "start/scope"+ "another/start/scope"+ - "/path" + + "/pathBis" + "" + ""; @@ -37,6 +38,7 @@ public class ConfigurationTest { ApplicationConfiguration bound = binder.bind(new ByteArrayInputStream(xml.getBytes())); + System.out.println(bound); assertEquals(sampleConfiguration(),bound); @@ -104,7 +106,7 @@ public class ConfigurationTest { .context("ctx") .name("name") .serviceClass("class") - .excludes(new Exclude(Arrays.asList("request-validation","request-accounting"),"/path")) + .includes(new Include("/pathBis")) .version("version") .description("desc") .persistence(new DefaultPersistence("target")); diff --git a/src/test/java/test/application/StartupTest.java b/src/test/java/test/application/StartupTest.java index 8f0457a..aecc38f 100644 --- a/src/test/java/test/application/StartupTest.java +++ b/src/test/java/test/application/StartupTest.java @@ -15,10 +15,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.File; -import java.util.HashSet; -import java.util.Set; -import org.gcube.common.resources.gcore.GCoreEndpoint; import org.gcube.common.resources.gcore.Resource; import org.gcube.informationsystem.publisher.ScopedPublisher; import org.gcube.informationsystem.publisher.exception.RegistryNotFoundException; @@ -36,8 +33,8 @@ import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mockito; -import utils.TestUtils.Box; import app.SomeApp; +import utils.TestUtils.Box; public class StartupTest { @@ -214,7 +211,7 @@ public class StartupTest { assertEquals(active,context.lifecycle().state()); - Set runningScopes = new HashSet<>(context.profile(GCoreEndpoint.class).scopes().asCollection()); + //Set runningScopes = new HashSet<>(context.profile(GCoreEndpoint.class).scopes().asCollection()); //assertEquals(singleton(vre),runningScopes); diff --git a/src/test/java/utils/TestProvider.java b/src/test/java/utils/TestProvider.java index 6d1de8a..1d7a295 100644 --- a/src/test/java/utils/TestProvider.java +++ b/src/test/java/utils/TestProvider.java @@ -2,7 +2,6 @@ package utils; import javax.servlet.ServletContext; -import org.gcube.informationsystem.publisher.RegistryPublisher; import org.gcube.informationsystem.publisher.ScopedPublisher; import org.gcube.smartgears.configuration.application.ApplicationConfiguration; import org.gcube.smartgears.configuration.application.ApplicationExtensions;