parent
a285c20b38
commit
f54efc1e4e
|
@ -38,12 +38,6 @@ public class Constants {
|
||||||
|
|
||||||
public static final String container_profile_file_path_copy = "ghn.xml.copy";
|
public static final String container_profile_file_path_copy = "ghn.xml.copy";
|
||||||
|
|
||||||
/**
|
|
||||||
* The container lifecycle configuration resource path.
|
|
||||||
*/
|
|
||||||
public static final String container_handlers_file_path = "/META-INF/container-handlers.xml";
|
|
||||||
|
|
||||||
public static final String container_handlers_file_name = "gcube-container-handlers.xml";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The library configuration resource path.
|
* The library configuration resource path.
|
||||||
|
@ -62,24 +56,11 @@ public class Constants {
|
||||||
public static final long default_container_publication_frequency_in_seconds = 60;
|
public static final long default_container_publication_frequency_in_seconds = 60;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The application configuration resource path.
|
* The application configuration resource path.
|
||||||
*/
|
*/
|
||||||
public static final String configuration_file_path = "/WEB-INF/gcube-app.xml";
|
public static final String configuration_file_path = "/WEB-INF/gcube-app.xml";
|
||||||
|
|
||||||
/**
|
|
||||||
* The application lifecycle configuration resource path.
|
|
||||||
*/
|
|
||||||
public static final String handlers_file_path = "/WEB-INF/gcube-handlers.xml";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default application lifecycle configuration resource path.
|
|
||||||
*/
|
|
||||||
public static final String default_handlers_file_path = "/META-INF/default-handlers.xml";
|
|
||||||
|
|
||||||
public static final String application_handlers_file_name = "gcube-application-handlers.xml";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wildcard exclude directive.
|
* The wildcard exclude directive.
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package org.gcube.smartgears.configuration.application;
|
package org.gcube.smartgears.configuration.application;
|
||||||
|
|
||||||
import static org.gcube.smartgears.utils.Utils.*;
|
import static org.gcube.smartgears.utils.Utils.closeSafely;
|
||||||
|
import static org.gcube.smartgears.utils.Utils.unchecked;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -12,7 +15,11 @@ import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
import org.gcube.smartgears.extensions.ApplicationExtension;
|
import org.gcube.smartgears.extensions.ApplicationExtension;
|
||||||
import org.gcube.smartgears.handlers.application.ApplicationHandler;
|
import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler;
|
||||||
|
import org.gcube.smartgears.handlers.application.RequestHandler;
|
||||||
|
import org.gcube.smartgears.handlers.application.lifecycle.ProfileManager;
|
||||||
|
import org.gcube.smartgears.handlers.application.request.RequestAccounting;
|
||||||
|
import org.gcube.smartgears.handlers.application.request.RequestValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds {@link ApplicationConfiguration}s to and from XML serialisations.
|
* Binds {@link ApplicationConfiguration}s to and from XML serialisations.
|
||||||
|
@ -54,25 +61,27 @@ public class ApplicationConfigurationBinder {
|
||||||
* @return the handlers
|
* @return the handlers
|
||||||
* @throws RuntimeException if the serialisation is invalid
|
* @throws RuntimeException if the serialisation is invalid
|
||||||
*/
|
*/
|
||||||
public ApplicationHandlers bindHandlers(InputStream stream) {
|
public ApplicationHandlers bindHandlers(ClassLoader classLoader) {
|
||||||
|
|
||||||
//collects handler classes
|
List<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();
|
||||||
Set<Class<?>> classes = scanForHandlers();
|
|
||||||
|
//ADDING BASE Handler (order is important)
|
||||||
try {
|
requestHandlers.add(new RequestValidator());
|
||||||
|
requestHandlers.add(new RequestAccounting());
|
||||||
JAXBContext ctx = JAXBContext.newInstance(classes.toArray(new Class<?>[0]));
|
|
||||||
|
//TODO scan RequestHAndler form classloader
|
||||||
return (ApplicationHandlers) ctx.createUnmarshaller().unmarshal(stream);
|
|
||||||
|
|
||||||
} catch (JAXBException e) {
|
List<ApplicationLifecycleHandler> lifecycleHandlers = new LinkedList<ApplicationLifecycleHandler>();
|
||||||
|
|
||||||
throw unchecked(e);
|
//ADDING BASE Handler (order is important)
|
||||||
|
lifecycleHandlers.add(new ProfileManager());
|
||||||
}
|
|
||||||
finally {
|
|
||||||
closeSafely(stream);
|
//TODO scan ApplicationLifecycleHandler form classloader
|
||||||
}
|
|
||||||
|
return new ApplicationHandlers(lifecycleHandlers, requestHandlers);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,28 +112,7 @@ public class ApplicationConfigurationBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Set<Class<?>> scanForHandlers() throws RuntimeException {
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
ServiceLoader<ApplicationHandler> handlerLoader = (ServiceLoader) ServiceLoader.load(ApplicationHandler.class);
|
|
||||||
|
|
||||||
Set<Class<?>> scanned = new HashSet<Class<?>>();
|
|
||||||
|
|
||||||
for (ApplicationHandler<?> handler : handlerLoader) {
|
|
||||||
Class<?> handlerClass = handler.getClass();
|
|
||||||
if (handlerClass.isInterface() || handlerClass.getModifiers() == Modifier.ABSTRACT)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
scanned.add(handlerClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
//add top-level configuration
|
|
||||||
scanned.add(ApplicationHandlers.class);
|
|
||||||
|
|
||||||
return scanned;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<Class<?>> scanForExtensions() throws RuntimeException {
|
private Set<Class<?>> scanForExtensions() throws RuntimeException {
|
||||||
|
|
||||||
|
@ -146,4 +134,8 @@ public class ApplicationConfigurationBinder {
|
||||||
|
|
||||||
return scanned;
|
return scanned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void scanForApplicationHandlers(ClassLoader currentClassLoader) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
package org.gcube.smartgears.configuration.application;
|
package org.gcube.smartgears.configuration.application;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.LinkedList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.xml.bind.Unmarshaller;
|
|
||||||
import javax.xml.bind.annotation.XmlAnyElement;
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import org.gcube.common.validator.ValidationError;
|
|
||||||
import org.gcube.common.validator.Validator;
|
|
||||||
import org.gcube.common.validator.ValidatorFactory;
|
|
||||||
import org.gcube.common.validator.annotations.IsValid;
|
|
||||||
import org.gcube.smartgears.handlers.application.ApplicationHandler;
|
import org.gcube.smartgears.handlers.application.ApplicationHandler;
|
||||||
import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler;
|
import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler;
|
||||||
import org.gcube.smartgears.handlers.application.RequestHandler;
|
import org.gcube.smartgears.handlers.application.RequestHandler;
|
||||||
import org.w3c.dom.Element;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ApplicationHandler}s that manage the application.
|
* The {@link ApplicationHandler}s that manage the application.
|
||||||
|
@ -23,24 +13,24 @@ import org.w3c.dom.Element;
|
||||||
* @author Fabio Simeoni
|
* @author Fabio Simeoni
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name="handlers")
|
|
||||||
public class ApplicationHandlers {
|
public class ApplicationHandlers {
|
||||||
|
|
||||||
|
|
||||||
@XmlElement(name="lifecycle") @IsValid
|
private List<ApplicationLifecycleHandler> lifecycleHandlers = new LinkedList<ApplicationLifecycleHandler>();
|
||||||
private LifecycleHandlers lifecycleHandlers = new LifecycleHandlers();
|
|
||||||
|
|
||||||
@XmlElement(name="request") @IsValid
|
private List<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();
|
||||||
private RequestHandlers requestHandlers = new RequestHandlers();
|
|
||||||
|
|
||||||
public ApplicationHandlers() {}
|
public ApplicationHandlers(List<ApplicationLifecycleHandler> lifecycleHandlers, List<RequestHandler> requestHandlers) {
|
||||||
|
this.lifecycleHandlers = lifecycleHandlers;
|
||||||
|
this.requestHandlers = requestHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link ApplicationLifecycleHandler}s for the service.
|
* Returns the {@link ApplicationLifecycleHandler}s for the service.
|
||||||
* @return the lifecycle handlers
|
* @return the lifecycle handlers
|
||||||
*/
|
*/
|
||||||
public List<ApplicationLifecycleHandler> lifecycleHandlers() {
|
public List<ApplicationLifecycleHandler> lifecycleHandlers() {
|
||||||
return lifecycleHandlers.values;
|
return lifecycleHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,8 +38,8 @@ public class ApplicationHandlers {
|
||||||
* @param handlers the lifecycle handlers
|
* @param handlers the lifecycle handlers
|
||||||
* @return this configuration
|
* @return this configuration
|
||||||
*/
|
*/
|
||||||
public ApplicationHandlers set(ApplicationLifecycleHandler ... handlers) {
|
public ApplicationHandlers setLifecycleHandlers(List<ApplicationLifecycleHandler> handlers) {
|
||||||
this.lifecycleHandlers = new LifecycleHandlers(Arrays.asList(handlers));
|
this.lifecycleHandlers = handlers;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +48,7 @@ public class ApplicationHandlers {
|
||||||
* @return the lifetime handlers
|
* @return the lifetime handlers
|
||||||
*/
|
*/
|
||||||
public List<RequestHandler> requestHandlers() {
|
public List<RequestHandler> requestHandlers() {
|
||||||
return requestHandlers.values;
|
return requestHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,75 +56,11 @@ public class ApplicationHandlers {
|
||||||
* @param handlers the request handlers
|
* @param handlers the request handlers
|
||||||
* @return this configuration
|
* @return this configuration
|
||||||
*/
|
*/
|
||||||
public ApplicationHandlers set(RequestHandler ... handlers) {
|
public ApplicationHandlers setRequetHandlers(List<RequestHandler> handlers) {
|
||||||
this.requestHandlers = new RequestHandlers(Arrays.asList(handlers));
|
this.requestHandlers = handlers;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate() {
|
|
||||||
|
|
||||||
List<String> msgs = new ArrayList<String>();
|
|
||||||
|
|
||||||
Validator validator = ValidatorFactory.validator();
|
|
||||||
|
|
||||||
for (ValidationError error : validator.validate(this))
|
|
||||||
msgs.add(error.toString());
|
|
||||||
|
|
||||||
if (!msgs.isEmpty())
|
|
||||||
throw new IllegalStateException("invalid configuration: "+msgs);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////// HELPER BINDING CLASSES
|
|
||||||
|
|
||||||
//used internally to introduce level of nesting in JAXB whilst preserving arbitrary extension
|
|
||||||
|
|
||||||
private static class LifecycleHandlers {
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
LifecycleHandlers() { //needed for deserialisation
|
|
||||||
}
|
|
||||||
|
|
||||||
LifecycleHandlers(List<ApplicationLifecycleHandler> handlers) {
|
|
||||||
this.values=handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlAnyElement(lax=true)
|
|
||||||
List<ApplicationLifecycleHandler> values = new ArrayList<ApplicationLifecycleHandler>();
|
|
||||||
|
|
||||||
|
|
||||||
//since we use @AnyElement, after deserialisation, we check there are no DOM elements
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
void afterUnmarshal(Unmarshaller u, Object parent) {
|
|
||||||
for (Object o : values)
|
|
||||||
if (o instanceof Element)
|
|
||||||
throw new RuntimeException("invalid handler detected in configuration: "+Element.class.cast(o).getLocalName());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//used internally to introduce level of nesting in JAXB whilst preserving arbitrary extension
|
|
||||||
private static class RequestHandlers {
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
RequestHandlers() { //needed for deserialisation
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestHandlers(List<RequestHandler> handlers) {
|
|
||||||
this.values=handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlAnyElement(lax=true)
|
|
||||||
List<RequestHandler> values = new ArrayList<RequestHandler>();
|
|
||||||
|
|
||||||
//since we use @AnyElement, after deserialisation, we check there are no DOM elements
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
void afterUnmarshal(Unmarshaller u, Object parent) {
|
|
||||||
for (Object o : values)
|
|
||||||
if (o instanceof Element)
|
|
||||||
throw new RuntimeException("invalid handler detected in configuration: "+Element.class.cast(o).getLocalName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mergeWith(ApplicationHandlers other){
|
public void mergeWith(ApplicationHandlers other){
|
||||||
List<ApplicationLifecycleHandler> lifecycles = other.lifecycleHandlers();
|
List<ApplicationLifecycleHandler> lifecycles = other.lifecycleHandlers();
|
||||||
|
|
|
@ -85,8 +85,6 @@ public class BaseConfiguration {
|
||||||
this.infrastructure = infrastructure;
|
this.infrastructure = infrastructure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
package org.gcube.smartgears.configuration.container;
|
package org.gcube.smartgears.configuration.container;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlTransient;
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
|
|
||||||
|
@ -23,14 +19,8 @@ import org.gcube.common.validator.annotations.NotNull;
|
||||||
import org.gcube.smartgears.configuration.Mode;
|
import org.gcube.smartgears.configuration.Mode;
|
||||||
import org.gcube.smartgears.configuration.ProxyAddress;
|
import org.gcube.smartgears.configuration.ProxyAddress;
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
||||||
import org.gcube.smartgears.persistence.LocalPersistence;
|
|
||||||
import org.gcube.smartgears.persistence.PersistenceWriter;
|
import org.gcube.smartgears.persistence.PersistenceWriter;
|
||||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||||
import org.gcube.smartgears.security.Credentials;
|
|
||||||
import org.gcube.smartgears.security.DefaultAuthorizationProvider;
|
|
||||||
import org.gcube.smartgears.utils.Utils;
|
|
||||||
import org.ini4j.Ini;
|
|
||||||
import org.ini4j.Profile.Section;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The configuration of the container.
|
* The configuration of the container.
|
||||||
|
@ -69,6 +59,35 @@ public class ContainerConfiguration {
|
||||||
@NotNull @IsValid
|
@NotNull @IsValid
|
||||||
private AuthorizationProvider authorizationProvider;
|
private AuthorizationProvider authorizationProvider;
|
||||||
|
|
||||||
|
|
||||||
|
protected void setBaseConfiguration(BaseConfiguration baseConfiguration) {
|
||||||
|
this.baseConfiguration = baseConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setProperties(Map<String, String> properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSite(Site site) {
|
||||||
|
this.site = site;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setProxy(ProxyAddress proxy) {
|
||||||
|
this.proxy = proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAccountingFallbackLocation(String accountingFallbackLocation) {
|
||||||
|
this.accountingFallbackLocation = accountingFallbackLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPersistenceManager(PersistenceWriter persistenceManager) {
|
||||||
|
this.persistenceManager = persistenceManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAuthorizationProvider(AuthorizationProvider authorizationProvider) {
|
||||||
|
this.authorizationProvider = authorizationProvider;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the management mode for the container.
|
* Returns the management mode for the container.
|
||||||
* @return the management mode
|
* @return the management mode
|
||||||
|
@ -243,116 +262,14 @@ public class ContainerConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ContainerConfiguration load(InputStream stream) {
|
@Override
|
||||||
try {
|
public String toString() {
|
||||||
Ini configurator = new Ini(stream);
|
return "ContainerConfiguration [baseConfiguration=" + baseConfiguration + ", properties=" + properties
|
||||||
ContainerConfiguration conf = new ContainerConfiguration();
|
+ ", site=" + site + ", proxy=" + proxy + ", accountingFallbackLocation=" + accountingFallbackLocation
|
||||||
|
+ ", persistenceManager=" + persistenceManager.getClass().getSimpleName()
|
||||||
Section nodeSection = configurator.get("node");
|
+ ", authorizationProvider=" + authorizationProvider.getClass().getSimpleName() + "]";
|
||||||
if (nodeSection != null ) {
|
|
||||||
BaseConfiguration nodeConf = new BaseConfiguration();
|
|
||||||
nodeSection.to(nodeConf);
|
|
||||||
conf.baseConfiguration = nodeConf;
|
|
||||||
}
|
|
||||||
|
|
||||||
Section propertiesSection = configurator.get("properties");
|
|
||||||
if (propertiesSection!=null)
|
|
||||||
conf.properties = propertiesSection.entrySet().stream()
|
|
||||||
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
|
||||||
|
|
||||||
Section siteSection = configurator.get("site");
|
|
||||||
if (siteSection != null) {
|
|
||||||
Site siteConf = new Site();
|
|
||||||
siteSection.to(siteConf);
|
|
||||||
conf.site = siteConf;
|
|
||||||
}
|
|
||||||
|
|
||||||
initAuthorizationPart(configurator, conf);
|
|
||||||
|
|
||||||
initPersistencePart(configurator, conf);
|
|
||||||
|
|
||||||
initProxyPart(configurator, conf);
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: find a solution for this shit
|
|
||||||
String location = Utils.home()+"/state";
|
|
||||||
File dir = new File(location);
|
|
||||||
if (!dir.exists())
|
|
||||||
dir.mkdirs();
|
|
||||||
conf.accountingFallbackLocation = location;
|
|
||||||
// END Shit
|
|
||||||
|
|
||||||
return conf;
|
|
||||||
}catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initProxyPart(Ini configurator, ContainerConfiguration conf) throws Exception{
|
|
||||||
Section proxySection = configurator.get("proxy");
|
|
||||||
if (proxySection != null) {
|
|
||||||
ProxyAddress proxyConf = new ProxyAddress();
|
|
||||||
proxySection.to(proxyConf);
|
|
||||||
conf.proxy = proxyConf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initPersistencePart(Ini configurator, ContainerConfiguration conf) throws Exception{
|
|
||||||
Section persistenceSection = configurator.get("persistence");
|
|
||||||
if (persistenceSection != null) {
|
|
||||||
String type = persistenceSection.get("class");
|
|
||||||
if (type ==null)
|
|
||||||
throw new Exception("ini file error: type not found in \"persistence\" section");
|
|
||||||
PersistenceWriter persistenceWriter;
|
|
||||||
try {
|
|
||||||
Object persistenceImpl = Class.forName(type).newInstance();
|
|
||||||
persistenceWriter = PersistenceWriter.class.cast(persistenceImpl);
|
|
||||||
}catch (Exception e) {
|
|
||||||
throw new Exception("ini file error: invalid persistence type in \"persistence\" section", e);
|
|
||||||
}
|
|
||||||
persistenceSection.to(persistenceWriter);
|
|
||||||
conf.persistenceManager = persistenceWriter;
|
|
||||||
} else {
|
|
||||||
String location = Utils.home()+"/state";
|
|
||||||
File dir = new File(location);
|
|
||||||
if (!dir.exists())
|
|
||||||
dir.mkdirs();
|
|
||||||
conf.persistenceManager = new LocalPersistence(location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initAuthorizationPart(Ini configurator, ContainerConfiguration conf) throws Exception{
|
|
||||||
Section authorizationSection = configurator.get("authorization");
|
|
||||||
if (authorizationSection != null) {
|
|
||||||
|
|
||||||
String provider = authorizationSection.get("provider");
|
|
||||||
AuthorizationProvider authProvider;
|
|
||||||
if (provider!=null) {
|
|
||||||
try {
|
|
||||||
Object authProviderImpl = Class.forName(provider).newInstance();
|
|
||||||
authProvider = AuthorizationProvider.class.cast(authProviderImpl);
|
|
||||||
}catch (Exception e) {
|
|
||||||
throw new Exception("ini file error: invalid provider type in \"authorization\" section", e);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
authProvider = new DefaultAuthorizationProvider();
|
|
||||||
|
|
||||||
|
|
||||||
String type = authorizationSection.get("credentials.class");
|
|
||||||
if (type ==null)
|
|
||||||
throw new Exception("ini file error: credentials type not found in \"authorization\" section");
|
|
||||||
Credentials credentials;
|
|
||||||
try {
|
|
||||||
Object credentialsImpl = Class.forName(type).newInstance();
|
|
||||||
credentials = Credentials.class.cast(credentialsImpl);
|
|
||||||
}catch (Exception e) {
|
|
||||||
throw new Exception("ini file error: invalid credentials type in \"authorization\" section", e);
|
|
||||||
}
|
|
||||||
authorizationSection.to(credentials, "credentials.");
|
|
||||||
|
|
||||||
authProvider.connect(credentials);
|
|
||||||
|
|
||||||
conf.authorizationProvider = authProvider;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,18 +1,26 @@
|
||||||
package org.gcube.smartgears.configuration.container;
|
package org.gcube.smartgears.configuration.container;
|
||||||
|
|
||||||
import static org.gcube.smartgears.utils.Utils.*;
|
import java.io.File;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.lang.reflect.Modifier;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.LinkedList;
|
||||||
import java.util.ServiceLoader;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
|
|
||||||
|
import org.gcube.smartgears.configuration.ProxyAddress;
|
||||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||||
|
import org.gcube.smartgears.handlers.container.lifecycle.AccountingManager;
|
||||||
|
import org.gcube.smartgears.handlers.container.lifecycle.ProfileContainerManager;
|
||||||
|
import org.gcube.smartgears.persistence.LocalPersistence;
|
||||||
|
import org.gcube.smartgears.persistence.PersistenceWriter;
|
||||||
|
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||||
|
import org.gcube.smartgears.security.AuthorizationProviderFactory;
|
||||||
|
import org.gcube.smartgears.security.Credentials;
|
||||||
|
import org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory;
|
||||||
import org.gcube.smartgears.utils.Utils;
|
import org.gcube.smartgears.utils.Utils;
|
||||||
|
import org.ini4j.Ini;
|
||||||
|
import org.ini4j.Profile.Section;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds {@link ContainerConfiguration}s to and from XML serialisations.
|
* Binds {@link ContainerConfiguration}s to and from XML serialisations.
|
||||||
|
@ -22,31 +30,117 @@ import org.gcube.smartgears.utils.Utils;
|
||||||
*/
|
*/
|
||||||
public class ContainerConfigurationBinder {
|
public class ContainerConfigurationBinder {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a {@link ContainerConfiguration} from its XML serialisation.
|
|
||||||
*
|
|
||||||
* @param stream the serialisation
|
|
||||||
* @return the configuration
|
|
||||||
* @throws RuntimeException if the serialisation is invalid
|
|
||||||
*/
|
|
||||||
public ContainerConfiguration bind(InputStream stream) {
|
|
||||||
|
|
||||||
|
public ContainerConfiguration load(InputStream stream) {
|
||||||
try {
|
try {
|
||||||
|
Ini configurator = new Ini(stream);
|
||||||
|
ContainerConfiguration conf = new ContainerConfiguration();
|
||||||
|
|
||||||
JAXBContext ctx = JAXBContext.newInstance(ContainerConfiguration.class);
|
Section nodeSection = configurator.get("node");
|
||||||
|
if (nodeSection != null ) {
|
||||||
|
BaseConfiguration nodeConf = new BaseConfiguration();
|
||||||
|
nodeSection.to(nodeConf);
|
||||||
|
conf.setBaseConfiguration(nodeConf);
|
||||||
|
}
|
||||||
|
|
||||||
ContainerConfiguration config = (ContainerConfiguration) ctx.createUnmarshaller().unmarshal(stream);
|
Section propertiesSection = configurator.get("properties");
|
||||||
|
if (propertiesSection!=null)
|
||||||
|
conf.setProperties(propertiesSection.entrySet().stream()
|
||||||
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
|
||||||
|
|
||||||
|
Section siteSection = configurator.get("site");
|
||||||
|
if (siteSection != null) {
|
||||||
|
Site siteConf = new Site();
|
||||||
|
siteSection.to(siteConf);
|
||||||
|
conf.setSite(siteConf);
|
||||||
|
}
|
||||||
|
|
||||||
|
initAuthorizationPart(configurator, conf);
|
||||||
|
|
||||||
return config;
|
initPersistencePart(configurator, conf);
|
||||||
|
|
||||||
} catch (JAXBException e) {
|
initProxyPart(configurator, conf);
|
||||||
|
|
||||||
throw new RuntimeException("invalid container configuration", e);
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: find a solution for this shit
|
||||||
|
String location = Utils.home()+"/state";
|
||||||
|
File dir = new File(location);
|
||||||
|
if (!dir.exists())
|
||||||
|
dir.mkdirs();
|
||||||
|
conf.setAccountingFallbackLocation(location);
|
||||||
|
// END Shit
|
||||||
|
|
||||||
|
return conf;
|
||||||
|
}catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
finally {
|
}
|
||||||
|
|
||||||
|
private void initProxyPart(Ini configurator, ContainerConfiguration conf) throws Exception{
|
||||||
|
Section proxySection = configurator.get("proxy");
|
||||||
|
if (proxySection != null) {
|
||||||
|
ProxyAddress proxyConf = new ProxyAddress();
|
||||||
|
proxySection.to(proxyConf);
|
||||||
|
conf.setProxy(proxyConf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPersistencePart(Ini configurator, ContainerConfiguration conf) throws Exception{
|
||||||
|
Section persistenceSection = configurator.get("persistence");
|
||||||
|
if (persistenceSection != null) {
|
||||||
|
String type = persistenceSection.get("class");
|
||||||
|
if (type ==null)
|
||||||
|
throw new Exception("ini file error: type not found in \"persistence\" section");
|
||||||
|
PersistenceWriter persistenceWriter;
|
||||||
|
try {
|
||||||
|
Object persistenceImpl = Class.forName(type).newInstance();
|
||||||
|
persistenceWriter = PersistenceWriter.class.cast(persistenceImpl);
|
||||||
|
}catch (Exception e) {
|
||||||
|
throw new Exception("ini file error: invalid persistence type in \"persistence\" section", e);
|
||||||
|
}
|
||||||
|
persistenceSection.to(persistenceWriter);
|
||||||
|
conf.setPersistenceManager(persistenceWriter);
|
||||||
|
} else {
|
||||||
|
String location = Utils.home()+"/state";
|
||||||
|
File dir = new File(location);
|
||||||
|
if (!dir.exists())
|
||||||
|
dir.mkdirs();
|
||||||
|
conf.setPersistenceManager(new LocalPersistence(location));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAuthorizationPart(Ini configurator, ContainerConfiguration conf) throws Exception{
|
||||||
|
Section authorizationSection = configurator.get("authorization");
|
||||||
|
if (authorizationSection != null) {
|
||||||
|
|
||||||
Utils.closeSafely(stream);
|
String provider = authorizationSection.get("factory");
|
||||||
|
AuthorizationProviderFactory<?> authProviderFactory;
|
||||||
|
if (provider!=null) {
|
||||||
|
try {
|
||||||
|
Object authProviderImpl = Class.forName(provider).newInstance();
|
||||||
|
authProviderFactory = AuthorizationProviderFactory.class.cast(authProviderImpl);
|
||||||
|
}catch (Exception e) {
|
||||||
|
throw new Exception("ini file error: invalid provider type in \"authorization\" section", e);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
authProviderFactory = new DefaultAuthorizationProviderFactory();
|
||||||
|
|
||||||
|
|
||||||
|
String type = authorizationSection.get("credentials.class");
|
||||||
|
if (type ==null)
|
||||||
|
throw new Exception("ini file error: credentials type not found in \"authorization\" section");
|
||||||
|
Credentials credentials;
|
||||||
|
try {
|
||||||
|
Object credentialsImpl = Class.forName(type).newInstance();
|
||||||
|
credentials = Credentials.class.cast(credentialsImpl);
|
||||||
|
}catch (Exception e) {
|
||||||
|
throw new Exception("ini file error: invalid credentials type in \"authorization\" section", e);
|
||||||
|
}
|
||||||
|
authorizationSection.to(credentials, "credentials.");
|
||||||
|
|
||||||
|
AuthorizationProvider authProvider = authProviderFactory.connect(credentials);
|
||||||
|
|
||||||
|
conf.setAuthorizationProvider(authProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,45 +151,27 @@ public class ContainerConfigurationBinder {
|
||||||
* @return the handlers
|
* @return the handlers
|
||||||
* @throws RuntimeException if the serialisation is invalid
|
* @throws RuntimeException if the serialisation is invalid
|
||||||
*/
|
*/
|
||||||
public ContainerHandlers bindHandlers(InputStream stream) {
|
public List<ContainerHandler> bindHandlers(ClassLoader classloader) {
|
||||||
|
|
||||||
//collects handler classes
|
LinkedList<ContainerHandler> handlers = new LinkedList<ContainerHandler>();
|
||||||
Set<Class<?>> classes = scanForConfigurationElements();
|
|
||||||
|
//ADDING BASE Handler (order is important)
|
||||||
try {
|
handlers.add(new AccountingManager());
|
||||||
|
handlers.add(new ProfileContainerManager());
|
||||||
JAXBContext ctx = JAXBContext.newInstance(classes.toArray(new Class<?>[0]));
|
|
||||||
|
handlers.addAll(scanForContainerHadlers(classloader));
|
||||||
return (ContainerHandlers) ctx.createUnmarshaller().unmarshal(stream);
|
|
||||||
|
return handlers;
|
||||||
} catch (JAXBException e) {
|
|
||||||
|
|
||||||
throw unchecked(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Set<Class<?>> scanForConfigurationElements() throws RuntimeException {
|
private List<? extends ContainerHandler> scanForContainerHadlers(ClassLoader classloader) throws RuntimeException {
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
//TODO: scan for Container Handler
|
||||||
ServiceLoader<ContainerHandler> handlerLoader = (ServiceLoader) ServiceLoader.load(ContainerHandler.class);
|
|
||||||
|
return Collections.emptyList();
|
||||||
Set<Class<?>> scanned = new HashSet<Class<?>>();
|
|
||||||
|
|
||||||
for (ContainerHandler handler : handlerLoader) {
|
|
||||||
Class<?> handlerClass = handler.getClass();
|
|
||||||
if (handlerClass.isInterface() || handlerClass.getModifiers() == Modifier.ABSTRACT)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
scanned.add(handlerClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
//add top-level configuration
|
|
||||||
scanned.add(ContainerHandlers.class);
|
|
||||||
|
|
||||||
return scanned;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
package org.gcube.smartgears.configuration.container;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAnyElement;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link ContainerHandler}s that manage the application.
|
|
||||||
*
|
|
||||||
* @author Fabio Simeoni
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@XmlRootElement(name="handlers")
|
|
||||||
public class ContainerHandlers {
|
|
||||||
|
|
||||||
@XmlAnyElement(lax=true)
|
|
||||||
List<ContainerHandler> handlers = new ArrayList<ContainerHandler>();
|
|
||||||
|
|
||||||
public ContainerHandlers() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link ContainerHandler}s for the service.
|
|
||||||
* @return the lifecycle handlers
|
|
||||||
*/
|
|
||||||
public List<ContainerHandler> get() {
|
|
||||||
return handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the {@link ContainerHandler}s for the service.
|
|
||||||
* @param handlers the lifecycle handlers
|
|
||||||
* @return this configuration
|
|
||||||
*/
|
|
||||||
public ContainerHandlers set(ContainerHandler ... handlers) {
|
|
||||||
this.handlers = Arrays.asList(handlers);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mergeWith(ContainerHandlers other){
|
|
||||||
List<ContainerHandler> handlers = other.get();
|
|
||||||
for (ContainerHandler handler : handlers)
|
|
||||||
if (!this.get().contains(handler))
|
|
||||||
this.get().add(handler);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,8 +5,6 @@ package org.gcube.smartgears.handlers.container.lifecycle;
|
||||||
|
|
||||||
import static org.gcube.smartgears.Constants.accounting_management;
|
import static org.gcube.smartgears.Constants.accounting_management;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
|
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
|
||||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||||
import org.gcube.smartgears.handlers.container.ContainerLifecycleEvent;
|
import org.gcube.smartgears.handlers.container.ContainerLifecycleEvent;
|
||||||
|
@ -16,7 +14,6 @@ import org.slf4j.LoggerFactory;
|
||||||
/**
|
/**
|
||||||
* @author Luca Frosini (ISTI - CNR)
|
* @author Luca Frosini (ISTI - CNR)
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name = accounting_management)
|
|
||||||
public class AccountingManager extends ContainerHandler {
|
public class AccountingManager extends ContainerHandler {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(AccountingManager.class);
|
private static Logger logger = LoggerFactory.getLogger(AccountingManager.class);
|
||||||
|
|
|
@ -19,8 +19,6 @@ import static org.gcube.smartgears.lifecycle.container.ContainerState.active;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import org.gcube.common.events.Observes;
|
import org.gcube.common.events.Observes;
|
||||||
import org.gcube.common.resources.gcore.HostingNode;
|
import org.gcube.common.resources.gcore.HostingNode;
|
||||||
import org.gcube.smartgears.configuration.Mode;
|
import org.gcube.smartgears.configuration.Mode;
|
||||||
|
@ -52,10 +50,9 @@ import org.slf4j.LoggerFactory;
|
||||||
* @author Fabio Simeoni
|
* @author Fabio Simeoni
|
||||||
* @see ProfileBuilder
|
* @see ProfileBuilder
|
||||||
*/
|
*/
|
||||||
@XmlRootElement(name = profile_management)
|
public class ProfileContainerManager extends ContainerHandler {
|
||||||
public class ProfileManager extends ContainerHandler {
|
|
||||||
|
|
||||||
private static Logger log = LoggerFactory.getLogger(ProfileManager.class);
|
private static Logger log = LoggerFactory.getLogger(ProfileContainerManager.class);
|
||||||
|
|
||||||
private ContainerContext context;
|
private ContainerContext context;
|
||||||
|
|
|
@ -83,7 +83,6 @@ public class ApplicationManager {
|
||||||
registerObservers();
|
registerObservers();
|
||||||
|
|
||||||
ApplicationHandlers handlers = provider().handlersFor(context);
|
ApplicationHandlers handlers = provider().handlersFor(context);
|
||||||
handlers.validate();
|
|
||||||
|
|
||||||
ApplicationExtensions extensions = provider().extensionsFor(context);
|
ApplicationExtensions extensions = provider().extensionsFor(context);
|
||||||
extensions.validate();
|
extensions.validate();
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Set;
|
||||||
import org.gcube.common.events.Observes;
|
import org.gcube.common.events.Observes;
|
||||||
import org.gcube.common.events.Observes.Kind;
|
import org.gcube.common.events.Observes.Kind;
|
||||||
import org.gcube.smartgears.configuration.Mode;
|
import org.gcube.smartgears.configuration.Mode;
|
||||||
import org.gcube.smartgears.configuration.container.ContainerHandlers;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
import org.gcube.smartgears.context.container.ContainerContext;
|
import org.gcube.smartgears.context.container.ContainerContext;
|
||||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||||
|
@ -61,18 +60,15 @@ public class ContainerManager {
|
||||||
|
|
||||||
saveContainerState();
|
saveContainerState();
|
||||||
|
|
||||||
ContainerHandlers handlers = provider().containerHandlers();
|
List<ContainerHandler> handlers = provider().containerHandlers();
|
||||||
|
|
||||||
log.trace("managing container lifecycle with {}", handlers.get());
|
log.trace("managing container lifecycle with {}", handlers);
|
||||||
|
|
||||||
startHandlers(handlers.get());
|
|
||||||
|
startHandlers(handlers);
|
||||||
|
|
||||||
context.lifecycle().moveTo(active);
|
context.lifecycle().moveTo(active);
|
||||||
|
|
||||||
log.trace("loading keys for starting token ...");
|
|
||||||
//loadKeyForToken(context.configuration().startTokens());
|
|
||||||
log.trace("keys loaded for starting token ...");
|
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
catch(RuntimeException e) {
|
catch(RuntimeException e) {
|
||||||
|
@ -103,10 +99,9 @@ public class ContainerManager {
|
||||||
//List<String> tokensToRemove = new ArrayList<String>();
|
//List<String> tokensToRemove = new ArrayList<String>();
|
||||||
context.configuration().validate();
|
context.configuration().validate();
|
||||||
Set<String> foundContexts;
|
Set<String> foundContexts;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
foundContexts = context.configuration().allowedContexts();
|
foundContexts = context.configuration().authorizationProvider().getAllowedContexts();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("error authorizing container",e);
|
log.error("error authorizing container",e);
|
||||||
throw new RuntimeException("error authorizing container, moving the container to failed",e);
|
throw new RuntimeException("error authorizing container, moving the container to failed",e);
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
package org.gcube.smartgears.provider;
|
package org.gcube.smartgears.provider;
|
||||||
|
|
||||||
import static org.gcube.smartgears.Constants.application_handlers_file_name;
|
|
||||||
import static org.gcube.smartgears.Constants.configuration_file_path;
|
import static org.gcube.smartgears.Constants.configuration_file_path;
|
||||||
import static org.gcube.smartgears.Constants.container_configuraton_file_path;
|
import static org.gcube.smartgears.Constants.container_configuraton_file_path;
|
||||||
import static org.gcube.smartgears.Constants.container_handlers_file_name;
|
|
||||||
import static org.gcube.smartgears.Constants.container_handlers_file_path;
|
|
||||||
import static org.gcube.smartgears.Constants.container_profile_file_path;
|
import static org.gcube.smartgears.Constants.container_profile_file_path;
|
||||||
import static org.gcube.smartgears.Constants.default_extensions_file_path;
|
import static org.gcube.smartgears.Constants.default_extensions_file_path;
|
||||||
import static org.gcube.smartgears.Constants.default_handlers_file_path;
|
|
||||||
import static org.gcube.smartgears.Constants.extensions_file_path;
|
import static org.gcube.smartgears.Constants.extensions_file_path;
|
||||||
import static org.gcube.smartgears.Constants.ghn_home_env;
|
import static org.gcube.smartgears.Constants.ghn_home_env;
|
||||||
import static org.gcube.smartgears.Constants.ghn_home_property;
|
import static org.gcube.smartgears.Constants.ghn_home_property;
|
||||||
import static org.gcube.smartgears.Constants.handlers_file_path;
|
|
||||||
import static org.gcube.smartgears.Constants.library_configuration_file_path;
|
import static org.gcube.smartgears.Constants.library_configuration_file_path;
|
||||||
import static org.gcube.smartgears.Constants.profile_file_path;
|
import static org.gcube.smartgears.Constants.profile_file_path;
|
||||||
|
|
||||||
|
@ -19,21 +14,13 @@ import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.net.URL;
|
import java.util.List;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.gcube.common.events.Hub;
|
import org.gcube.common.events.Hub;
|
||||||
import org.gcube.common.events.impl.DefaultHub;
|
import org.gcube.common.events.impl.DefaultHub;
|
||||||
import org.gcube.common.scan.ClasspathScanner;
|
|
||||||
import org.gcube.common.scan.ClasspathScannerFactory;
|
|
||||||
import org.gcube.common.scan.matchers.NameMatcher;
|
|
||||||
import org.gcube.common.scan.resources.ClasspathResource;
|
|
||||||
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
|
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
|
||||||
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
||||||
import org.gcube.smartgears.configuration.Mode;
|
import org.gcube.smartgears.configuration.Mode;
|
||||||
|
@ -44,7 +31,6 @@ import org.gcube.smartgears.configuration.application.ApplicationHandlers;
|
||||||
import org.gcube.smartgears.configuration.application.BridgedApplicationConfiguration;
|
import org.gcube.smartgears.configuration.application.BridgedApplicationConfiguration;
|
||||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||||
import org.gcube.smartgears.configuration.container.ContainerConfigurationBinder;
|
import org.gcube.smartgears.configuration.container.ContainerConfigurationBinder;
|
||||||
import org.gcube.smartgears.configuration.container.ContainerHandlers;
|
|
||||||
import org.gcube.smartgears.configuration.library.SmartGearsConfiguration;
|
import org.gcube.smartgears.configuration.library.SmartGearsConfiguration;
|
||||||
import org.gcube.smartgears.configuration.library.SmartGearsConfigurationBinder;
|
import org.gcube.smartgears.configuration.library.SmartGearsConfigurationBinder;
|
||||||
import org.gcube.smartgears.context.Properties;
|
import org.gcube.smartgears.context.Properties;
|
||||||
|
@ -52,6 +38,7 @@ import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
import org.gcube.smartgears.context.application.DefaultApplicationContext;
|
import org.gcube.smartgears.context.application.DefaultApplicationContext;
|
||||||
import org.gcube.smartgears.context.container.ContainerContext;
|
import org.gcube.smartgears.context.container.ContainerContext;
|
||||||
import org.gcube.smartgears.context.container.DefaultContainerContext;
|
import org.gcube.smartgears.context.container.DefaultContainerContext;
|
||||||
|
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||||
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
||||||
import org.gcube.smartgears.lifecycle.container.ContainerLifecycle;
|
import org.gcube.smartgears.lifecycle.container.ContainerLifecycle;
|
||||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||||
|
@ -78,7 +65,7 @@ public class DefaultProvider implements Provider {
|
||||||
protected DefaultProvider(File configFile) {
|
protected DefaultProvider(File configFile) {
|
||||||
this.configFile = configFile;
|
this.configFile = configFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected DefaultProvider(){};
|
protected DefaultProvider(){};
|
||||||
|
|
||||||
|
@ -87,18 +74,6 @@ public class DefaultProvider implements Provider {
|
||||||
|
|
||||||
if(containerContext==null){
|
if(containerContext==null){
|
||||||
ContainerConfiguration configuration = containerConfiguration();
|
ContainerConfiguration configuration = containerConfiguration();
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (configuration.persistence()==null) {
|
|
||||||
String location = Utils.home()+"/state";
|
|
||||||
File dir = new File(location);
|
|
||||||
if (!dir.exists())
|
|
||||||
dir.mkdirs();
|
|
||||||
configuration.persistence(new LocalPersistence(location));
|
|
||||||
|
|
||||||
log.trace("setting persistence location for container @ {}",dir.getAbsolutePath());
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Hub hub = new DefaultHub();
|
Hub hub = new DefaultHub();
|
||||||
|
|
||||||
|
@ -128,17 +103,11 @@ public class DefaultProvider implements Provider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerHandlers containerHandlers() {
|
public List<ContainerHandler> containerHandlers() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
//TODO retrieve handler classes
|
|
||||||
|
|
||||||
if (config == null)
|
|
||||||
throw new IllegalStateException("invalid distribution: cannot find " + container_handlers_file_path);
|
|
||||||
|
|
||||||
ContainerConfigurationBinder binder = new ContainerConfigurationBinder();
|
ContainerConfigurationBinder binder = new ContainerConfigurationBinder();
|
||||||
ContainerHandlers defaultHandlers = binder.bindHandlers(config);
|
|
||||||
|
|
||||||
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
if (currentClassLoader.getParent()!=null && !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())){
|
if (currentClassLoader.getParent()!=null && !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())){
|
||||||
|
@ -146,35 +115,7 @@ public class DefaultProvider implements Provider {
|
||||||
currentClassLoader = currentClassLoader.getParent();
|
currentClassLoader = currentClassLoader.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<ContainerHandler> defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||||
try{
|
|
||||||
if (currentClassLoader instanceof URLClassLoader){
|
|
||||||
URL[] urls = ((URLClassLoader) currentClassLoader).getURLs() ;
|
|
||||||
|
|
||||||
if (urls!=null && urls.length>0){
|
|
||||||
ClasspathScanner scanner = ClasspathScannerFactory.scanner(new HashSet<URL>(Arrays.asList(urls)));
|
|
||||||
Collection<ClasspathResource> resources = scanner.scan(new NameMatcher(container_handlers_file_name));
|
|
||||||
|
|
||||||
for (URL url: urls)
|
|
||||||
log.trace("URL: "+ url.toString());
|
|
||||||
|
|
||||||
if (resources==null || resources.isEmpty())
|
|
||||||
log.info("no custom container handlers found in the classpath");
|
|
||||||
|
|
||||||
for (ClasspathResource res : resources){
|
|
||||||
try{
|
|
||||||
ContainerHandlers customHandlers= binder.bindHandlers(res.stream());
|
|
||||||
defaultHandlers.mergeWith(customHandlers);
|
|
||||||
log.trace("container hadlers found in {}",res.name());
|
|
||||||
}catch(Exception e){
|
|
||||||
log.warn("error loading not default container handlers {}",res.name(),e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else log.info("this classloader is not instance of {} : ",URLClassLoader.class.getName(), currentClassLoader.getClass().getName());
|
|
||||||
}catch(Exception e){
|
|
||||||
log.warn("cannot load custom handlers for container from the root classloader",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultHandlers;
|
return defaultHandlers;
|
||||||
|
|
||||||
|
@ -250,15 +191,10 @@ public class DefaultProvider implements Provider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// it's in a library, using
|
|
||||||
InputStream defaultHandlersStream = getClass().getResourceAsStream(default_handlers_file_path);
|
|
||||||
|
|
||||||
if (defaultHandlersStream == null)
|
|
||||||
throw new IllegalStateException("invalid distribution: cannot find " + default_handlers_file_path);
|
|
||||||
|
|
||||||
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder();
|
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder();
|
||||||
|
|
||||||
ApplicationHandlers defaultHandlers = binder.bindHandlers(defaultHandlersStream);
|
|
||||||
|
|
||||||
//searching for smartegars related application handlers in the common classloader
|
//searching for smartegars related application handlers in the common classloader
|
||||||
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||||
|
@ -267,40 +203,8 @@ public class DefaultProvider implements Provider {
|
||||||
currentClassLoader = currentClassLoader.getParent();
|
currentClassLoader = currentClassLoader.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplicationHandlers defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||||
try{
|
|
||||||
if (currentClassLoader instanceof URLClassLoader){
|
|
||||||
URL[] urls = ((URLClassLoader) currentClassLoader).getURLs() ;
|
|
||||||
|
|
||||||
if (urls!=null && urls.length>0){
|
|
||||||
ClasspathScanner scanner = ClasspathScannerFactory.scanner(new HashSet<URL>(Arrays.asList(urls)));
|
|
||||||
Collection<ClasspathResource> resources = scanner.scan(new NameMatcher(application_handlers_file_name));
|
|
||||||
if (resources==null || resources.isEmpty())
|
|
||||||
log.info("no custom smartgears related application handlers found in the classpath");
|
|
||||||
|
|
||||||
for (ClasspathResource res : resources){
|
|
||||||
try{
|
|
||||||
ApplicationHandlers customHandlers= binder.bindHandlers(res.stream());
|
|
||||||
defaultHandlers.mergeWith(customHandlers);
|
|
||||||
log.trace("application hadlers found in {}",res.name());
|
|
||||||
}catch(Exception e){
|
|
||||||
log.warn("error loading smartgears related application handlers {}",res.name(),e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch(Exception e){
|
|
||||||
log.warn("cannot load smartgears related handlers for application from the root classloader",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream appSpecificHandlersStream = context.application().getResourceAsStream(handlers_file_path);
|
|
||||||
|
|
||||||
if (appSpecificHandlersStream !=null ){
|
|
||||||
defaultHandlers.mergeWith(binder.bindHandlers(appSpecificHandlersStream));
|
|
||||||
log.trace("{} uses default lifecycle with app spceific handler as it includes {}", context.name(), handlers_file_path);
|
|
||||||
} else
|
|
||||||
log.trace("{} uses the default lifecycle as it does not include {}", context.name(), handlers_file_path);
|
|
||||||
|
|
||||||
return defaultHandlers;
|
return defaultHandlers;
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,9 +297,9 @@ public class DefaultProvider implements Provider {
|
||||||
private ContainerConfiguration containerConfiguration() {
|
private ContainerConfiguration containerConfiguration() {
|
||||||
|
|
||||||
if (configFile==null) {
|
if (configFile==null) {
|
||||||
|
|
||||||
String home = Utils.home();
|
String home = Utils.home();
|
||||||
|
|
||||||
if (home == null)
|
if (home == null)
|
||||||
throw new IllegalStateException("invalid node configuration: the environment variable " + ghn_home_env
|
throw new IllegalStateException("invalid node configuration: the environment variable " + ghn_home_env
|
||||||
+ " or the system property " + ghn_home_property + " must be defined");
|
+ " or the system property " + ghn_home_property + " must be defined");
|
||||||
|
@ -407,7 +311,7 @@ public class DefaultProvider implements Provider {
|
||||||
|
|
||||||
configFile = new File(homeDir,container_configuraton_file_path);
|
configFile = new File(homeDir,container_configuraton_file_path);
|
||||||
|
|
||||||
|
|
||||||
log.trace("reading container configuration @ {} ", configFile.getAbsolutePath());
|
log.trace("reading container configuration @ {} ", configFile.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,11 +320,11 @@ public class DefaultProvider implements Provider {
|
||||||
|
|
||||||
ContainerConfiguration configuration;
|
ContainerConfiguration configuration;
|
||||||
try (InputStream stream = new FileInputStream(configFile)){
|
try (InputStream stream = new FileInputStream(configFile)){
|
||||||
configuration= ContainerConfiguration.load(stream);
|
configuration= new ContainerConfigurationBinder().load(stream);
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
throw new IllegalStateException("invalid node configuration: file "+configFile.getAbsolutePath()+" is invalid");
|
throw new IllegalStateException("invalid node configuration: file "+configFile.getAbsolutePath()+" is invalid", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package org.gcube.smartgears.provider;
|
package org.gcube.smartgears.provider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationExtensions;
|
import org.gcube.smartgears.configuration.application.ApplicationExtensions;
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationHandlers;
|
import org.gcube.smartgears.configuration.application.ApplicationHandlers;
|
||||||
import org.gcube.smartgears.configuration.container.ContainerHandlers;
|
|
||||||
import org.gcube.smartgears.configuration.library.SmartGearsConfiguration;
|
import org.gcube.smartgears.configuration.library.SmartGearsConfiguration;
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
import org.gcube.smartgears.context.application.ApplicationContext;
|
||||||
import org.gcube.smartgears.context.container.ContainerContext;
|
import org.gcube.smartgears.context.container.ContainerContext;
|
||||||
|
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +39,7 @@ public interface Provider {
|
||||||
* Returns the handlers associated with the container.
|
* Returns the handlers associated with the container.
|
||||||
* @return the handlers
|
* @return the handlers
|
||||||
*/
|
*/
|
||||||
ContainerHandlers containerHandlers();
|
List<ContainerHandler> containerHandlers();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,5 @@ import java.util.Set;
|
||||||
|
|
||||||
public interface AuthorizationProvider {
|
public interface AuthorizationProvider {
|
||||||
|
|
||||||
void connect(Credentials credentials) throws Exception;
|
|
||||||
|
|
||||||
Set<String> getAllowedContexts();
|
Set<String> getAllowedContexts();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.gcube.smartgears.security;
|
||||||
|
|
||||||
|
public interface AuthorizationProviderFactory<T extends AuthorizationProvider> {
|
||||||
|
|
||||||
|
T connect(Credentials credentials);
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,9 @@ public class SimpleCredentials implements Credentials{
|
||||||
|
|
||||||
@NotNull @NotEmpty
|
@NotNull @NotEmpty
|
||||||
String secret;
|
String secret;
|
||||||
|
|
||||||
|
@NotNull @NotEmpty
|
||||||
|
String endpoint;
|
||||||
|
|
||||||
public String getClientID() {
|
public String getClientID() {
|
||||||
return clientID;
|
return clientID;
|
||||||
|
@ -17,6 +20,14 @@ public class SimpleCredentials implements Credentials{
|
||||||
|
|
||||||
public void setClientID(String clientID) {
|
public void setClientID(String clientID) {
|
||||||
this.clientID = clientID;
|
this.clientID = clientID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEndpoint() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndpoint(String endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSecret() {
|
public String getSecret() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.gcube.smartgears.security;
|
package org.gcube.smartgears.security.defaults;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -11,6 +12,8 @@ import org.gcube.common.keycloak.model.AccessToken.Access;
|
||||||
import org.gcube.common.keycloak.model.ModelUtils;
|
import org.gcube.common.keycloak.model.ModelUtils;
|
||||||
import org.gcube.common.keycloak.model.TokenResponse;
|
import org.gcube.common.keycloak.model.TokenResponse;
|
||||||
import org.gcube.common.scope.impl.ScopeBean;
|
import org.gcube.common.scope.impl.ScopeBean;
|
||||||
|
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||||
|
import org.gcube.smartgears.security.SimpleCredentials;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -18,20 +21,20 @@ public class DefaultAuthorizationProvider implements AuthorizationProvider {
|
||||||
|
|
||||||
private static Logger LOG = LoggerFactory.getLogger(DefaultAuthorizationProvider.class);
|
private static Logger LOG = LoggerFactory.getLogger(DefaultAuthorizationProvider.class);
|
||||||
|
|
||||||
private SimpleCredentials credentials;
|
|
||||||
|
|
||||||
private KeycloakClient client = KeycloakClientFactory.newInstance();
|
private KeycloakClient client = KeycloakClientFactory.newInstance();
|
||||||
|
|
||||||
@Override
|
private SimpleCredentials credentials;
|
||||||
public void connect(Credentials credentials) {
|
|
||||||
this.credentials = (SimpleCredentials)credentials;
|
public DefaultAuthorizationProvider(SimpleCredentials credentials) {
|
||||||
|
this.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getAllowedContexts() {
|
public Set<String> getAllowedContexts() {
|
||||||
Set<String> contexts = new HashSet<String>();
|
Set<String> contexts = new HashSet<String>();
|
||||||
try {
|
try {
|
||||||
TokenResponse response = client.queryOIDCToken(credentials.getClientID(), credentials.getSecret());
|
TokenResponse response = client.queryOIDCToken(new URL(credentials.getEndpoint()), credentials.getClientID(), credentials.getSecret());
|
||||||
Map<String, Access> resourceAccess = ModelUtils.getAccessTokenFrom(response).getResourceAccess();
|
Map<String, Access> resourceAccess = ModelUtils.getAccessTokenFrom(response).getResourceAccess();
|
||||||
for (String context : resourceAccess.keySet()) {
|
for (String context : resourceAccess.keySet()) {
|
||||||
try {
|
try {
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.gcube.smartgears.security.defaults;
|
||||||
|
|
||||||
|
import org.gcube.smartgears.security.AuthorizationProviderFactory;
|
||||||
|
import org.gcube.smartgears.security.Credentials;
|
||||||
|
import org.gcube.smartgears.security.SimpleCredentials;
|
||||||
|
|
||||||
|
public class DefaultAuthorizationProviderFactory implements AuthorizationProviderFactory<DefaultAuthorizationProvider>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultAuthorizationProvider connect(Credentials credentials) {
|
||||||
|
if (!SimpleCredentials.class.isInstance(credentials))
|
||||||
|
throw new IllegalArgumentException("invalid credential type passed");
|
||||||
|
return new DefaultAuthorizationProvider((SimpleCredentials)credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<handlers>
|
|
||||||
<accounting-management />
|
|
||||||
<profile-management />
|
|
||||||
</handlers>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<handlers>
|
|
||||||
<lifecycle>
|
|
||||||
<profile-management />
|
|
||||||
</lifecycle>
|
|
||||||
<request>
|
|
||||||
<request-validation />
|
|
||||||
<request-accounting />
|
|
||||||
</request>
|
|
||||||
</handlers>
|
|
|
@ -1,4 +0,0 @@
|
||||||
org.gcube.smartgears.handlers.application.lifecycle.ProfileManager
|
|
||||||
org.gcube.smartgears.handlers.application.request.RequestValidator
|
|
||||||
org.gcube.smartgears.handlers.application.request.RequestAccounting
|
|
||||||
org.gcube.smartgears.handlers.application.request.RequestContextRetriever
|
|
|
@ -1,2 +0,0 @@
|
||||||
org.gcube.smartgears.handlers.container.lifecycle.ProfileManager
|
|
||||||
org.gcube.smartgears.handlers.container.lifecycle.AccountingManager
|
|
|
@ -1,187 +0,0 @@
|
||||||
package app;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.ws.rs.HttpMethod;
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.client.Client;
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
|
||||||
import javax.ws.rs.client.Invocation.Builder;
|
|
||||||
|
|
||||||
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
|
||||||
import org.gcube.common.authorization.library.provider.UserInfo;
|
|
||||||
import org.gcube.common.authorization.library.utils.Caller;
|
|
||||||
import org.gcube.smartgears.extensions.HttpExtension.Method;
|
|
||||||
import org.glassfish.jersey.client.ClientConfig;
|
|
||||||
import org.glassfish.jersey.client.ClientResponse;
|
|
||||||
import org.glassfish.jersey.logging.LoggingFeature;
|
|
||||||
|
|
||||||
import utils.TestUtils;
|
|
||||||
|
|
||||||
public class Request {
|
|
||||||
|
|
||||||
private String path="";
|
|
||||||
private String scope = TestUtils.scope;
|
|
||||||
|
|
||||||
//private OutBoundHeaders headers = new OutBoundHeaders();
|
|
||||||
private String method = HttpMethod.GET;
|
|
||||||
private String body = null;
|
|
||||||
private boolean logged = false;
|
|
||||||
Map<String, List<Object>> headers = new HashMap<>();
|
|
||||||
|
|
||||||
public static Request request() {
|
|
||||||
return new Request();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Request() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request at(String path) {
|
|
||||||
this.path=path;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request logging() {
|
|
||||||
logged=true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request inScope(String scope) {
|
|
||||||
this.scope=scope;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request with(String body) {
|
|
||||||
this.body=body;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request with(String name, String value) {
|
|
||||||
this.headers.put(name, Collections.singletonList(value));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request using(Method method) {
|
|
||||||
this.method=method.getValue();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String path() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String body() {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String method() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String scope() {
|
|
||||||
return scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientResponse make(final int port) {
|
|
||||||
|
|
||||||
|
|
||||||
// we make a scoped call in a separate thread, with which we then synchronize for completion.
|
|
||||||
// this helps isolate the caller's thread (Main normally) from the app's thread,
|
|
||||||
// starting with the scope itself.
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
class Box {
|
|
||||||
|
|
||||||
volatile WebApplicationException failure;
|
|
||||||
volatile ClientResponse response;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
final Box box = new Box();
|
|
||||||
|
|
||||||
new Thread() {
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
AuthorizationProvider.instance.set(new Caller(new UserInfo("test", new ArrayList<String>()),"DEFAULT"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
ClientConfig config = new ClientConfig();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Client client = ClientBuilder.newClient();
|
|
||||||
|
|
||||||
|
|
||||||
if (logged)
|
|
||||||
client.register(new LoggingFeature(Logger.getLogger(getClass().getName())));
|
|
||||||
|
|
||||||
Builder builder = client.target(address(path,port)).request();
|
|
||||||
builder.header("gcube-scope", scope);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (Entry<String,List<Object>> header : headers.entrySet())
|
|
||||||
for (Object value : header.getValue())
|
|
||||||
builder.header(header.getKey(), value);
|
|
||||||
|
|
||||||
if (method.equals(HttpMethod.DELETE))
|
|
||||||
builder.delete();
|
|
||||||
else {
|
|
||||||
|
|
||||||
System.err.println("making request @ "+address(path,port));
|
|
||||||
|
|
||||||
ClientResponse response = builder.method(method,ClientResponse.class);
|
|
||||||
|
|
||||||
//throws an exception if there response has error status
|
|
||||||
if (response.getStatus()>300)
|
|
||||||
throw new WebApplicationException(response.getStatus());
|
|
||||||
|
|
||||||
box.response=response;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (WebApplicationException t) {
|
|
||||||
box.failure=t;
|
|
||||||
}
|
|
||||||
|
|
||||||
latch.countDown();
|
|
||||||
};
|
|
||||||
}.start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (!latch.await(2000, TimeUnit.MILLISECONDS))
|
|
||||||
throw new RuntimeException("application has not responded in time");
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (box.failure !=null)
|
|
||||||
throw box.failure;
|
|
||||||
|
|
||||||
else
|
|
||||||
return box.response;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String address(String path, long port) {
|
|
||||||
|
|
||||||
path = (path.isEmpty() || path.startsWith("/"))?path:"/"+path;
|
|
||||||
|
|
||||||
return "http://localhost:" + port+ "/" + TestUtils.context_root+path;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,437 +0,0 @@
|
||||||
package app;
|
|
||||||
|
|
||||||
import static org.gcube.smartgears.Constants.configuration_file_path;
|
|
||||||
import static org.gcube.smartgears.Constants.extensions_file_path;
|
|
||||||
import static org.gcube.smartgears.Constants.ghn_home_property;
|
|
||||||
import static org.gcube.smartgears.Constants.handlers_file_path;
|
|
||||||
import static utils.TestUtils.context_root;
|
|
||||||
import static utils.TestUtils.context_root_path;
|
|
||||||
import static utils.TestUtils.location;
|
|
||||||
import static utils.TestUtils.servlet_name;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.apache.catalina.Wrapper;
|
|
||||||
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.ScopedPublisher;
|
|
||||||
import org.gcube.smartgears.Constants;
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationExtensions;
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationHandlers;
|
|
||||||
import org.gcube.smartgears.configuration.application.DefaultApplicationConfiguration;
|
|
||||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.managers.ContainerManager;
|
|
||||||
import org.gcube.smartgears.provider.ProviderFactory;
|
|
||||||
import org.glassfish.jersey.client.ClientResponse;
|
|
||||||
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
|
||||||
import org.jboss.shrinkwrap.api.asset.StringAsset;
|
|
||||||
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
|
|
||||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
|
||||||
import org.jboss.shrinkwrap.impl.base.path.BasicPath;
|
|
||||||
|
|
||||||
import utils.TestProvider;
|
|
||||||
import utils.TestUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulates a single-servlet application to be transformed into a gCube resource.
|
|
||||||
* <p>
|
|
||||||
* <ul>
|
|
||||||
* <li>uses a default configuration that can be customised (cf. {@link #configuration()});
|
|
||||||
* <li>can be configured with the default handlers (cf. {@link #useDefaultHandlers()}) or custom ones (
|
|
||||||
* {@link #handlers()}), including those that are not deployable through standard means, such as mocks (
|
|
||||||
* {@link #bypassHandlerDeployment()};
|
|
||||||
* <li>can be started to have a default behaviour when called, ({@link #start()}) or else a custom behaviour (
|
|
||||||
* {@link #startWith(Runnable)};
|
|
||||||
* </ul>
|
|
||||||
* can be called in a default scope ({@link #call()} or in a specific scope ({@link #callIn(String)}). Calls are blocking but always
|
|
||||||
* configured and executed in a separate thread;
|
|
||||||
*
|
|
||||||
* @author Fabio Simeoni
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SomeApp {
|
|
||||||
|
|
||||||
private final Tomcat tomcat = new Tomcat();
|
|
||||||
|
|
||||||
private WebArchive war = defaultWar();
|
|
||||||
|
|
||||||
private ContainerConfiguration containerConfiguration;
|
|
||||||
private ApplicationConfiguration configuration;
|
|
||||||
private ApplicationHandlers handlers = new ApplicationHandlers();
|
|
||||||
private ApplicationExtensions extensions = new ApplicationExtensions();
|
|
||||||
private TestProvider provider = new TestProvider(new File("src/test/resources/test-configuration.ini"));
|
|
||||||
private boolean deployHandlers = true;
|
|
||||||
private boolean deployExtensions = true;
|
|
||||||
private boolean deployConfiguration = true;
|
|
||||||
private boolean clean=true;
|
|
||||||
|
|
||||||
public SomeApp() {
|
|
||||||
|
|
||||||
if (ContainerManager.instance!=null)
|
|
||||||
ContainerManager.instance.stop(true);
|
|
||||||
|
|
||||||
tomcat.getConnector().setPort(0);
|
|
||||||
tomcat.setBaseDir(location);
|
|
||||||
|
|
||||||
System.setProperty(ghn_home_property,location);
|
|
||||||
|
|
||||||
containerConfiguration = defaultContainerConfiguration();
|
|
||||||
configuration = defaultConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a {@link TestProvider} to resolve dependencies at runtime.
|
|
||||||
*
|
|
||||||
* @param provider the provider
|
|
||||||
*/
|
|
||||||
public void set(TestProvider provider) {
|
|
||||||
this.provider = provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the test with the state left by previous run.
|
|
||||||
* <p>
|
|
||||||
* Use only within a single test!
|
|
||||||
*/
|
|
||||||
public void dirtyRun() {
|
|
||||||
this.clean = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configuration of the application.
|
|
||||||
* <p>
|
|
||||||
* The initial configuration is based on defaults, but can be changed and extended.
|
|
||||||
*
|
|
||||||
* @return the configuration
|
|
||||||
*/
|
|
||||||
public ApplicationConfiguration configuration() {
|
|
||||||
return configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the configuration of the containerConfiguration.
|
|
||||||
* <p>
|
|
||||||
* The initial configuration is based on defaults, but can be changed and extended.
|
|
||||||
*
|
|
||||||
* @return the configuration
|
|
||||||
*/
|
|
||||||
public ContainerConfiguration containerConfiguration() {
|
|
||||||
return containerConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the handlers that manage the application, none by default.
|
|
||||||
*
|
|
||||||
* @return the handlers
|
|
||||||
*/
|
|
||||||
public ApplicationHandlers handlers() {
|
|
||||||
return handlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoids deployment of the configured handlers in the application's WAR.
|
|
||||||
* <p>
|
|
||||||
* The handlers will instead be directly available at runtime.
|
|
||||||
*/
|
|
||||||
public void bypassHandlerDeployment() {
|
|
||||||
|
|
||||||
provider.use(handlers());
|
|
||||||
deployHandlers = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoids resource configuration deployment.
|
|
||||||
*/
|
|
||||||
public void asExternal() {
|
|
||||||
|
|
||||||
configuration.context(context_root_path);
|
|
||||||
containerConfiguration.app(configuration);
|
|
||||||
|
|
||||||
bypassConfigurationDeployment();
|
|
||||||
bypassExtensionsDeployment();
|
|
||||||
bypassHandlerDeployment();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoids resource configuration deployment.
|
|
||||||
*/
|
|
||||||
public void withExternal(ApplicationConfiguration config) {
|
|
||||||
|
|
||||||
config.context(context_root_path);
|
|
||||||
|
|
||||||
containerConfiguration.app(config.context()).merge(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void bypassConfigurationDeployment() {
|
|
||||||
|
|
||||||
deployConfiguration = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void usePublisher(ScopedPublisher publisher) {
|
|
||||||
|
|
||||||
provider.use(publisher);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses default handlers.
|
|
||||||
*/
|
|
||||||
public void useDefaultHandlers() {
|
|
||||||
|
|
||||||
deployHandlers = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the extensions of the application, none by default.
|
|
||||||
*
|
|
||||||
* @return the handlers
|
|
||||||
*/
|
|
||||||
public ApplicationExtensions extensions() {
|
|
||||||
return extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses default extensions.
|
|
||||||
*/
|
|
||||||
public void useDefaultExtensions() {
|
|
||||||
|
|
||||||
deployExtensions = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoids deployment of the configured extensions in the application's WAR.
|
|
||||||
* <p>
|
|
||||||
* The extensions will instead be directly available at runtime.
|
|
||||||
*/
|
|
||||||
public void bypassExtensionsDeployment() {
|
|
||||||
|
|
||||||
provider.use(extensions());
|
|
||||||
deployExtensions = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the application.
|
|
||||||
*
|
|
||||||
* @return the context of the application
|
|
||||||
*/
|
|
||||||
public ApplicationContext start() {
|
|
||||||
|
|
||||||
return startWith(new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
System.err.println("test servlet invoked with no particular task");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the application, injecting test logic in its single servlet
|
|
||||||
*
|
|
||||||
* @param test test logic
|
|
||||||
* @return the context of the application
|
|
||||||
*/
|
|
||||||
public ApplicationContext startWith(Runnable test) {
|
|
||||||
|
|
||||||
// install provider
|
|
||||||
ProviderFactory.testProvider(provider);
|
|
||||||
|
|
||||||
if (clean)
|
|
||||||
cleanupInstallation();
|
|
||||||
|
|
||||||
|
|
||||||
if (deployConfiguration)
|
|
||||||
deployConfiguration();
|
|
||||||
|
|
||||||
if (deployHandlers)
|
|
||||||
deployHandlers();
|
|
||||||
|
|
||||||
if (deployExtensions)
|
|
||||||
deployExtensions();
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
System.err.println("deploying with " + war.toString(true));
|
|
||||||
|
|
||||||
StandardContext ctx = (StandardContext) tomcat.addWebapp(context_root_path, warFile().getAbsolutePath());
|
|
||||||
|
|
||||||
// tells tomcat to look also for exploded directories such as this project's (finds initializer)
|
|
||||||
((StandardJarScanner) ctx.getJarScanner()).setScanAllDirectories(true);
|
|
||||||
|
|
||||||
//this starts webapp and always comes back
|
|
||||||
tomcat.start();
|
|
||||||
|
|
||||||
ApplicationContext context = provider.context;
|
|
||||||
|
|
||||||
if (context==null)
|
|
||||||
throw new RuntimeException("app failed @ startup");
|
|
||||||
|
|
||||||
Wrapper webapp = (Wrapper) tomcat.getHost().findChild(context_root_path).findChild(servlet_name);
|
|
||||||
|
|
||||||
if (webapp!=null) {
|
|
||||||
|
|
||||||
webapp.setServlet(new TestServlet(test));
|
|
||||||
|
|
||||||
//context.container().configuration().port(port());
|
|
||||||
|
|
||||||
containerConfiguration = context.container().configuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
return context;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retuens <code>true</code> if the application was successfully start in the container.
|
|
||||||
*
|
|
||||||
* @return <code>true</code> if the application was successfully start in the container
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
return tomcat.getHost().findChild("/" + context_root).findChild(servlet_name) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a request to the application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public String send(Request call) {
|
|
||||||
return (String) call.make(port()).getEntity();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a request to the application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ClientResponse httpSend(Request call) {
|
|
||||||
return call.make(port());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the application
|
|
||||||
*/
|
|
||||||
public void stop() {
|
|
||||||
|
|
||||||
try {
|
|
||||||
tomcat.stop();
|
|
||||||
tomcat.destroy();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("WARNING: could not clearly stop container:");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public File containerConfigurationFile() {
|
|
||||||
|
|
||||||
return new File(location,Constants.container_configuraton_file_path);
|
|
||||||
}
|
|
||||||
// helpers
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Includes the configuration in the application's WAR.
|
|
||||||
*/
|
|
||||||
private void deployConfiguration() {
|
|
||||||
|
|
||||||
String xml = TestUtils.bind(configuration());
|
|
||||||
|
|
||||||
System.err.println("deploying with configuration:\n" + xml);
|
|
||||||
|
|
||||||
war.addAsWebResource(new StringAsset(xml), new BasicPath(configuration_file_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Includes the handlers in the application's WAR.
|
|
||||||
*/
|
|
||||||
private void deployHandlers() {
|
|
||||||
|
|
||||||
String xml = TestUtils.bind(handlers());
|
|
||||||
|
|
||||||
System.err.println("deploying with handlers:\n" + xml);
|
|
||||||
|
|
||||||
war.addAsWebResource(new StringAsset(xml), new BasicPath(handlers_file_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Includes the extensions in the application's WAR.
|
|
||||||
*/
|
|
||||||
private void deployExtensions() {
|
|
||||||
|
|
||||||
String xml = TestUtils.bind(extensions());
|
|
||||||
|
|
||||||
System.err.println("deploying with extensions:\n" + xml);
|
|
||||||
|
|
||||||
war.addAsWebResource(new StringAsset(xml), new BasicPath(extensions_file_path));
|
|
||||||
}
|
|
||||||
|
|
||||||
private File warFile() {
|
|
||||||
|
|
||||||
File warFile = new File(location, "test.war");
|
|
||||||
|
|
||||||
if (warFile.exists() && !warFile.delete())
|
|
||||||
System.out.println("could not delete old deployment");; // seems safer than plain overwrite to avoid war corruption
|
|
||||||
|
|
||||||
war.as(ZipExporter.class).exportTo(warFile, true);
|
|
||||||
|
|
||||||
return warFile;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private WebArchive defaultWar() {
|
|
||||||
|
|
||||||
WebArchive war = ShrinkWrap.create(WebArchive.class);
|
|
||||||
war.setWebXML(new File("src/test/java/app/web.xml"));
|
|
||||||
return war;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApplicationConfiguration defaultConfiguration() {
|
|
||||||
|
|
||||||
return new DefaultApplicationConfiguration().serviceClass("test-class").name("test-app").version("1.0");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContainerConfiguration defaultContainerConfiguration() {
|
|
||||||
|
|
||||||
InputStream is = SomeApp.class.getResourceAsStream("/test-configuration.ini");
|
|
||||||
|
|
||||||
return ContainerConfiguration.load(is);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int port() {
|
|
||||||
return tomcat.getConnector().getLocalPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cleanupInstallation() {
|
|
||||||
|
|
||||||
System.out.println("cleaning installation in location "+location);
|
|
||||||
|
|
||||||
File installation = new File(location);
|
|
||||||
|
|
||||||
if (installation.exists())
|
|
||||||
try {
|
|
||||||
FileUtils.deleteDirectory(installation);
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
installation.mkdirs();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package app;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@WebServlet(name = "test", urlPatterns = "/test")
|
|
||||||
public class TestServlet extends HttpServlet {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private Runnable test;
|
|
||||||
|
|
||||||
public TestServlet(Runnable test) {
|
|
||||||
this.test=test;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest request,
|
|
||||||
HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
|
|
||||||
test.run();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<web-app>
|
|
||||||
|
|
||||||
<display-name>test-app</display-name>
|
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>test</servlet-name>
|
|
||||||
<servlet-class>app.TestServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>test</servlet-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
</web-app>
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package test;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
||||||
|
import org.gcube.smartgears.configuration.container.ContainerConfigurationBinder;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class BinderTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindConfig() throws Exception {
|
||||||
|
|
||||||
|
InputStream stream = BinderTest.class.getResourceAsStream("/container.ini");
|
||||||
|
|
||||||
|
ContainerConfiguration conf = new ContainerConfigurationBinder().load(stream);
|
||||||
|
System.out.println(conf.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.context.container.ContainerContext;
|
|
||||||
import org.gcube.smartgears.handlers.application.lifecycle.ProfileManager;
|
|
||||||
import org.gcube.smartgears.lifecycle.application.ApplicationState;
|
|
||||||
import org.gcube.smartgears.lifecycle.container.ContainerState;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class AppLifecycleTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void applicationGoesDownIfContainerDoes() {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager());
|
|
||||||
|
|
||||||
ApplicationContext actx = app.start();
|
|
||||||
|
|
||||||
assertEquals(ApplicationState.active,actx.lifecycle().state());
|
|
||||||
|
|
||||||
ContainerContext ctx = actx.container();
|
|
||||||
|
|
||||||
assertEquals(ContainerState.active,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
ctx.lifecycle().moveTo(ContainerState.stopped);
|
|
||||||
|
|
||||||
assertEquals(ApplicationState.stopped,actx.lifecycle().state());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,214 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static app.Request.request;
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.fail;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.application_failed_error;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.application_unavailable_error;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.request_not_authorized_error;
|
|
||||||
import static org.gcube.smartgears.lifecycle.application.ApplicationState.failed;
|
|
||||||
import static org.gcube.smartgears.lifecycle.application.ApplicationState.stopped;
|
|
||||||
import static utils.TestUtils.scope;
|
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
|
|
||||||
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
|
|
||||||
import org.gcube.smartgears.Constants;
|
|
||||||
import org.gcube.smartgears.configuration.application.Exclude;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.handlers.application.lifecycle.ProfileManager;
|
|
||||||
import org.gcube.smartgears.handlers.application.request.RequestValidator;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
|
|
||||||
public class CallValidationTest {
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void rejectsCallsWhenServiceIsInactive() {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
|
|
||||||
Runnable test = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
fail("call should have been rejected");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ApplicationContext context = app.startWith(test);
|
|
||||||
|
|
||||||
context.lifecycle().moveTo(stopped);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request());
|
|
||||||
}
|
|
||||||
catch(WebApplicationException e) {
|
|
||||||
assertEquals(application_unavailable_error.code(), e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
context.lifecycle().moveTo(failed);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request());
|
|
||||||
}
|
|
||||||
catch(WebApplicationException e) {
|
|
||||||
assertEquals(application_failed_error.code(), e.getResponse().getStatus());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void rejectsCallsWithoutScope() throws Throwable {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request().inScope(null));; //call in no scope
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
catch(WebApplicationException e) {
|
|
||||||
assertEquals(request_not_authorized_error.code(), e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void rejectsCallsWithBadScope() throws Throwable {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request().inScope("/bad/scope")); //call in no scope
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
catch(WebApplicationException e) {
|
|
||||||
assertEquals(invalid_request_error.code(), e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void propagatesScope() throws Throwable {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
Runnable test = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
assertEquals(scope,SecurityTokenProvider.instance.get());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.startWith(test);
|
|
||||||
|
|
||||||
app.send(request());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void respectsAllExcludeWildCard() throws Throwable {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.configuration().excludes().add(new Exclude(Constants.WILDCARD));
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
Runnable test = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.startWith(test);
|
|
||||||
|
|
||||||
app.send(request().inScope(null));
|
|
||||||
|
|
||||||
latch.await(500,TimeUnit.MILLISECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void respectsExcludeWildCard() throws Throwable {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.configuration().excludes().add(new Exclude("/path"+Constants.WILDCARD));
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
Runnable test = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.startWith(test);
|
|
||||||
|
|
||||||
app.send(request().at("path/test").inScope(null));
|
|
||||||
|
|
||||||
latch.await(500,TimeUnit.MILLISECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void respectsExactExclude() throws Throwable {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.configuration().excludes().add(new Exclude("/path"));
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager()).set(new RequestValidator());
|
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
Runnable test = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.startWith(test);
|
|
||||||
|
|
||||||
app.send(request().at("path").inScope(null));
|
|
||||||
|
|
||||||
latch.await(500,TimeUnit.MILLISECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,112 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationConfigurationBinder;
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationExtensions;
|
|
||||||
import org.gcube.smartgears.configuration.application.DefaultApplicationConfiguration;
|
|
||||||
import org.gcube.smartgears.configuration.application.Include;
|
|
||||||
import org.gcube.smartgears.extensions.ApplicationExtension;
|
|
||||||
import org.gcube.smartgears.persistence.LocalPersistence;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ConfigurationTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void configurationBinds() throws Exception {
|
|
||||||
|
|
||||||
String xml = "<application mode='offline' context='ctx' isSecure='true'>" +
|
|
||||||
"<name>name</name>" +
|
|
||||||
"<group>class</group>" +
|
|
||||||
"<version>version</version>" +
|
|
||||||
"<description>desc</description>" +
|
|
||||||
"<scope>start/scope</scope>"+
|
|
||||||
"<scope>another/start/scope</scope>"+
|
|
||||||
"<include>/pathBis</include>" +
|
|
||||||
"<persistence location='target'/>" +
|
|
||||||
"</application>";
|
|
||||||
|
|
||||||
|
|
||||||
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder();
|
|
||||||
|
|
||||||
ApplicationConfiguration bound = binder.bind(new ByteArrayInputStream(xml.getBytes()));
|
|
||||||
|
|
||||||
|
|
||||||
System.out.println(bound);
|
|
||||||
|
|
||||||
assertEquals(sampleConfiguration(),bound);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void extensionsBind() throws Exception {
|
|
||||||
|
|
||||||
String xml = "<extensions>" +
|
|
||||||
"<remote-management name='custom' mapping='custom' />" +
|
|
||||||
"</extensions>";
|
|
||||||
|
|
||||||
|
|
||||||
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder();
|
|
||||||
|
|
||||||
ApplicationExtensions bound = binder.bindExtensions(new ByteArrayInputStream(xml.getBytes()));
|
|
||||||
|
|
||||||
assertNotNull(bound.extensions());
|
|
||||||
assertEquals(1,bound.extensions().size());
|
|
||||||
|
|
||||||
ApplicationExtension ext = bound.extensions().get(0);
|
|
||||||
assertEquals("custom",ext.name());
|
|
||||||
assertEquals("custom",ext.mapping());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*@Test
|
|
||||||
public void configurationsMerge() throws Exception {
|
|
||||||
|
|
||||||
ApplicationConfiguration original = sampleConfiguration();
|
|
||||||
|
|
||||||
ApplicationConfiguration one = sampleConfiguration();
|
|
||||||
|
|
||||||
ApplicationConfiguration two = new DefaultApplicationConfiguration();
|
|
||||||
two.mode(Mode.online);
|
|
||||||
two.persistence(new DefaultPersistence(new File(".").getAbsolutePath()));
|
|
||||||
two.startScopes("yet/another/one");
|
|
||||||
|
|
||||||
one.merge(two);
|
|
||||||
|
|
||||||
assertEquals(one.mode(), two.mode());
|
|
||||||
assertEquals(one.name(), original.name());
|
|
||||||
assertEquals(one.persistence(), two.persistence());
|
|
||||||
|
|
||||||
Set<String> merged = new HashSet<>(original.startScopes());
|
|
||||||
|
|
||||||
merged.addAll(two.startScopes());
|
|
||||||
|
|
||||||
assertEquals(merged,one.startScopes());
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//helpers
|
|
||||||
|
|
||||||
private ApplicationConfiguration sampleConfiguration() {
|
|
||||||
|
|
||||||
|
|
||||||
return new DefaultApplicationConfiguration()
|
|
||||||
.context("ctx")
|
|
||||||
.name("name")
|
|
||||||
.serviceClass("class")
|
|
||||||
.includes(new Include("/pathBis"))
|
|
||||||
.version("version")
|
|
||||||
.description("desc")
|
|
||||||
.persistence(new LocalPersistence("target"));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,288 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static app.Request.request;
|
|
||||||
import static org.gcube.smartgears.Constants.accept;
|
|
||||||
import static org.gcube.smartgears.Constants.allow;
|
|
||||||
import static org.gcube.smartgears.Constants.content_type;
|
|
||||||
import static org.gcube.smartgears.extensions.ApiResource.handles;
|
|
||||||
import static org.gcube.smartgears.extensions.ApiResource.method;
|
|
||||||
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
|
|
||||||
import static org.gcube.smartgears.extensions.HttpExtension.Method.POST;
|
|
||||||
import static org.gcube.smartgears.extensions.HttpExtension.Method.PUT;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.incoming_contenttype_unsupported_error;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.method_unsupported_error;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.outgoing_contenttype_unsupported_error;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.resource_notfound_error;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.Constants;
|
|
||||||
import org.gcube.smartgears.extensions.ApiResource;
|
|
||||||
import org.gcube.smartgears.extensions.ApiSignature;
|
|
||||||
import org.gcube.smartgears.extensions.HttpController;
|
|
||||||
import org.gcube.smartgears.extensions.HttpExtension;
|
|
||||||
import org.glassfish.jersey.client.ClientResponse;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.Request;
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class ControllerTest {
|
|
||||||
|
|
||||||
String name = "name";
|
|
||||||
String extension_path = "/ext";
|
|
||||||
String extension_mapping = "/ext/*";
|
|
||||||
String resource_path = "/resource";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void dispatchesToResource() {
|
|
||||||
|
|
||||||
// returns a given type
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
|
|
||||||
|
|
||||||
// requires same type
|
|
||||||
Request request = request().at(resource()).with(accept, "text/plain");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
app.send(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void toleratesTrainingSlashes() {
|
|
||||||
|
|
||||||
// returns a given type
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
|
|
||||||
|
|
||||||
// requires same type
|
|
||||||
Request request = request().at(resource()).with(accept, "text/plain");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
app.send(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void handlesUnknownResources() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path);
|
|
||||||
|
|
||||||
// points to not existing resource
|
|
||||||
Request request = request().at(resource() + "/bad");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request);
|
|
||||||
fail();
|
|
||||||
} catch (WebApplicationException e) {
|
|
||||||
assertEquals(resource_notfound_error.code(), e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void handlesUnsupportedMethods() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET)).with(method(PUT));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).using(POST);
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request);
|
|
||||||
fail();
|
|
||||||
} catch (WebApplicationException e) {
|
|
||||||
assertEquals(method_unsupported_error.code(), e.getResponse().getStatus());
|
|
||||||
assertNotNull(e.getResponse().getHeaders().toString(),e.getResponse().getHeaders().get(allow));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void enforcesAcceptHeaders() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).with(accept, "text/xml");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request);
|
|
||||||
fail();
|
|
||||||
} catch (WebApplicationException e) {
|
|
||||||
assertEquals(outgoing_contenttype_unsupported_error.code(), e.getResponse().getStatus());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void enforcesAcceptHeadersEvenWhenResourceDeclaresNone() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).with(accept, "text/xml");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request);
|
|
||||||
fail();
|
|
||||||
} catch (WebApplicationException e) {
|
|
||||||
assertEquals(outgoing_contenttype_unsupported_error.code(), e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void enforcesMultiValuedAcceptHeader() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).with(accept, "text/xml").with(accept,"text/plain");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
app.send(request);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setsContentTypeIfUnsetAndUnambiguous() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain"));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).with(accept, "text/plain");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
ClientResponse response = app.httpSend(request);
|
|
||||||
|
|
||||||
assertTrue(response.getHeaders().get(content_type).get(0).contains("text/plain"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void doesntSetContentTypeIfUnsetButAmbiguous() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(GET).produces("text/plain","text/xml"));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).with(accept, "text/plain");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
ClientResponse response = app.httpSend(request);
|
|
||||||
|
|
||||||
System.out.println(response.getHeaders());
|
|
||||||
|
|
||||||
assertNull(response.getHeaders().get(content_type));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void enforcesMultiValuedContentTypeHeader() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(POST).accepts("application/xml"));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).using(POST).with(content_type, "text/xml").with(content_type,"text/plain");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request);
|
|
||||||
fail();
|
|
||||||
} catch (WebApplicationException e) {
|
|
||||||
assertEquals(incoming_contenttype_unsupported_error.code(), e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void acceptsContentTypeHeadersWhenResourceDeclaresNone() {
|
|
||||||
|
|
||||||
ApiSignature signature = handles(resource_path).with(method(POST));
|
|
||||||
|
|
||||||
Request request = request().at(resource()).using(POST).with(content_type, "text/xml");
|
|
||||||
|
|
||||||
SomeApp app = startAppWith(signature);
|
|
||||||
|
|
||||||
app.httpSend(request);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////// helpers
|
|
||||||
|
|
||||||
private String resource() {
|
|
||||||
return Constants.root_mapping + extension_path + resource_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
SomeApp startAppWith(ApiSignature signature) {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.extensions().set(controllerWith(signature));
|
|
||||||
|
|
||||||
app.bypassExtensionsDeployment();
|
|
||||||
app.bypassHandlerDeployment();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
HttpExtension controllerWith(final ApiSignature signature) {
|
|
||||||
return new HttpController(name, extension_mapping) {
|
|
||||||
|
|
||||||
{
|
|
||||||
addResources(new ApiResource(signature) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
|
|
||||||
IOException {
|
|
||||||
if (!supports(Method.valueOf(req.getMethod())))
|
|
||||||
super.doGet(req, resp);
|
|
||||||
else
|
|
||||||
resp.getWriter().write(req.getMethod() + " invoked @ " + signature.mapping());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
|
|
||||||
IOException {
|
|
||||||
if (!supports(Method.valueOf(req.getMethod())))
|
|
||||||
super.doPost(req, resp);
|
|
||||||
else
|
|
||||||
resp.getWriter().write(req.getMethod() + " invoked @ " + signature.mapping());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
|
|
||||||
IOException {
|
|
||||||
if (!supports(Method.valueOf(req.getMethod())))
|
|
||||||
super.doPut(req, resp);
|
|
||||||
else
|
|
||||||
resp.getWriter().write(req.getMethod() + " invoked @ " + signature.mapping());
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "SUT controller";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,184 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static app.Request.request;
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertNotNull;
|
|
||||||
import static junit.framework.Assert.fail;
|
|
||||||
import static org.gcube.smartgears.handlers.application.request.RequestError.invalid_request_error;
|
|
||||||
import static org.gcube.smartgears.lifecycle.application.ApplicationState.failed;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.Constants;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.extensions.ApplicationExtension;
|
|
||||||
import org.gcube.smartgears.extensions.HttpExtension;
|
|
||||||
import org.gcube.smartgears.extensions.resource.RemoteResource;
|
|
||||||
import org.gcube.smartgears.handlers.application.request.RequestError;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class ExtensionsTest {
|
|
||||||
|
|
||||||
String name = "name";
|
|
||||||
String extension_path="/ext";
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void areInstalledAndInitialised() {
|
|
||||||
|
|
||||||
|
|
||||||
final String response = "output";
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
ApplicationExtension extension = new HttpExtension(name,extension_path) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
|
||||||
assertNotNull(context()); //init has been invoked
|
|
||||||
res.getWriter().write(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.extensions().set(extension);
|
|
||||||
|
|
||||||
//we're only testing correct installation, not configuration now anything else
|
|
||||||
app.bypassExtensionsDeployment();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
String actual = app.send(request().at(Constants.root_mapping+extension_path));
|
|
||||||
|
|
||||||
assertEquals(response,actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
@XmlRootElement(name="unknown")
|
|
||||||
static class UnknownExtension extends HttpExtension {
|
|
||||||
|
|
||||||
UnknownExtension() {}
|
|
||||||
|
|
||||||
public UnknownExtension(String name, String mapping) {
|
|
||||||
super(name, mapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void failAppIfNotConfigured() {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.bypassHandlerDeployment();
|
|
||||||
|
|
||||||
app.extensions().set(new UnknownExtension(name,extension_path));
|
|
||||||
|
|
||||||
ApplicationContext context= app.start();
|
|
||||||
|
|
||||||
assertEquals(failed,context.lifecycle().state());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void failAppIfConfiguredBadly() {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
RemoteResource extension = new RemoteResource();
|
|
||||||
extension.name("");
|
|
||||||
extension.mapping("");
|
|
||||||
|
|
||||||
app.extensions().set(extension);
|
|
||||||
|
|
||||||
app.bypassHandlerDeployment();
|
|
||||||
|
|
||||||
ApplicationContext context= app.start();
|
|
||||||
|
|
||||||
assertEquals(failed,context.lifecycle().state());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void throwErrorsConvertedInHttpResponses() {
|
|
||||||
|
|
||||||
|
|
||||||
final RequestError error = invalid_request_error;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
ApplicationExtension extension = new HttpExtension(name,extension_path) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
|
||||||
error.fire();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.extensions().set(extension);
|
|
||||||
|
|
||||||
//we're only testing correct installation, not configuration now anything else
|
|
||||||
app.bypassExtensionsDeployment();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
app.send(request().at(Constants.root_mapping+extension_path));
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
catch(WebApplicationException e) {
|
|
||||||
|
|
||||||
assertEquals(error.code(),e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void areManagedLikeNativeServlets() {
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
ApplicationExtension extension = new HttpExtension(name,extension_path) {
|
|
||||||
@Override
|
|
||||||
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.extensions().set(extension);
|
|
||||||
|
|
||||||
app.bypassExtensionsDeployment();
|
|
||||||
|
|
||||||
//installs default filters
|
|
||||||
app.useDefaultHandlers();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
//call in no scope
|
|
||||||
try {
|
|
||||||
app.send(request().at(Constants.root_mapping+extension_path).inScope(null));
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
catch(WebApplicationException e) {
|
|
||||||
|
|
||||||
assertEquals((String)e.getResponse().getEntity(),invalid_request_error.code(),e.getResponse().getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.*;
|
|
||||||
import static org.gcube.smartgears.Constants.*;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import org.gcube.common.resources.gcore.GCoreEndpoint;
|
|
||||||
import org.gcube.common.resources.gcore.Resources;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.handlers.application.lifecycle.ProfileManager;
|
|
||||||
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class ProfileManagementTest {
|
|
||||||
|
|
||||||
public static ApplicationContext ctx;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void startApp() {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
app.handlers().set(new ProfileManager());
|
|
||||||
|
|
||||||
ctx = app.start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void createsStoresAndPublishesAValidProfile() throws Exception {
|
|
||||||
|
|
||||||
GCoreEndpoint profile = ctx.profile();
|
|
||||||
|
|
||||||
assertNotNull(profile);
|
|
||||||
|
|
||||||
//assert profile has been created
|
|
||||||
File file = ctx.configuration().persistence().file(profile_file_path);
|
|
||||||
assertTrue(file.exists());
|
|
||||||
|
|
||||||
assertFalse(profile.scopes().isEmpty());
|
|
||||||
|
|
||||||
Resources.validate(profile);
|
|
||||||
|
|
||||||
//assert status matches lifecycle's current state
|
|
||||||
ApplicationLifecycle lc = ctx.lifecycle();
|
|
||||||
|
|
||||||
assertEquals(profile.profile().deploymentData().status(),lc.state().remoteForm());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loadsAndUpdatesProfile() throws Exception {
|
|
||||||
|
|
||||||
SomeApp runtwice = new SomeApp();
|
|
||||||
|
|
||||||
runtwice.handlers().set(new ProfileManager());
|
|
||||||
|
|
||||||
runtwice.dirtyRun();
|
|
||||||
|
|
||||||
ApplicationContext ctx = runtwice.start();
|
|
||||||
|
|
||||||
|
|
||||||
GCoreEndpoint profile = ctx.profile();
|
|
||||||
|
|
||||||
assertNotNull(profile);
|
|
||||||
|
|
||||||
Resources.validate(profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static app.Request.request;
|
|
||||||
import static org.gcube.smartgears.Constants.application_xml;
|
|
||||||
import static org.gcube.smartgears.Constants.content_type;
|
|
||||||
import static org.gcube.smartgears.extensions.HttpExtension.Method.GET;
|
|
||||||
import static org.gcube.smartgears.extensions.HttpExtension.Method.POST;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
|
|
||||||
import org.gcube.common.resources.gcore.GCoreEndpoint;
|
|
||||||
import org.gcube.common.resources.gcore.Resources;
|
|
||||||
import org.gcube.smartgears.Constants;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.extensions.resource.ConfigurationResource;
|
|
||||||
import org.gcube.smartgears.extensions.resource.FrontPageResource;
|
|
||||||
import org.gcube.smartgears.extensions.resource.LifecycleResource;
|
|
||||||
import org.gcube.smartgears.extensions.resource.LifecycleResource.State;
|
|
||||||
import org.gcube.smartgears.extensions.resource.ProfileResource;
|
|
||||||
import org.gcube.smartgears.lifecycle.application.ApplicationState;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.Request;
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class RemoteResourceTest {
|
|
||||||
|
|
||||||
static final String path = "/resource";
|
|
||||||
static JAXBContext jaxb;
|
|
||||||
static ApplicationContext context;
|
|
||||||
|
|
||||||
static SomeApp app;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void setup() throws Exception {
|
|
||||||
|
|
||||||
jaxb = JAXBContext.newInstance(State.class);
|
|
||||||
|
|
||||||
app = new SomeApp();
|
|
||||||
|
|
||||||
app.useDefaultHandlers();
|
|
||||||
app.useDefaultExtensions();
|
|
||||||
|
|
||||||
context = app.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void showsFrontpage() throws Exception {
|
|
||||||
|
|
||||||
// unscoped request
|
|
||||||
Request request = request().at(resource(FrontPageResource.mapping)).inScope(null);
|
|
||||||
|
|
||||||
app.send(request);
|
|
||||||
|
|
||||||
//Thread.sleep(50000); enable to check interactively in browser
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void showsConfiguration() throws Exception {
|
|
||||||
|
|
||||||
//unscoped request
|
|
||||||
Request request = request().at(resource(ConfigurationResource.mapping)).inScope(null);
|
|
||||||
|
|
||||||
app.send(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void showsProfile() throws Exception {
|
|
||||||
|
|
||||||
//unscoped request
|
|
||||||
Request request = request().at(resource(ProfileResource.mapping)).inScope(null);
|
|
||||||
|
|
||||||
String outcome = app.send(request);
|
|
||||||
|
|
||||||
GCoreEndpoint profile = Resources.unmarshal(GCoreEndpoint.class, new StringReader(outcome));
|
|
||||||
|
|
||||||
assertEquals(context.profile().id(), profile.id());
|
|
||||||
assertEquals(context.profile().profile().deploymentData().status(), profile.profile().deploymentData().status());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void currentState() throws Exception {
|
|
||||||
|
|
||||||
Request request = request().at(resource(LifecycleResource.mapping)).using(GET).inScope(null);
|
|
||||||
|
|
||||||
String outcome = app.send(request);
|
|
||||||
|
|
||||||
State state = (State) jaxb.createUnmarshaller().unmarshal(new StringReader(outcome));
|
|
||||||
|
|
||||||
assertEquals(context.lifecycle().state(),ApplicationState.valueOf(state.value));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
|
||||||
public void changeState() throws Exception {
|
|
||||||
|
|
||||||
ApplicationState newstate = ApplicationState.stopped;
|
|
||||||
|
|
||||||
assertFalse(context.lifecycle().state()==newstate);
|
|
||||||
|
|
||||||
Request request = request().at(resource(LifecycleResource.mapping)).using(POST).inScope(null)
|
|
||||||
.with(content_type, application_xml).with("<state>stopped</state>");
|
|
||||||
|
|
||||||
app.httpSend(request);
|
|
||||||
|
|
||||||
assertTrue(context.lifecycle().state()==newstate);
|
|
||||||
|
|
||||||
request = request().at(resource(LifecycleResource.mapping)).using(POST).inScope(null)
|
|
||||||
.with(content_type, application_xml).with("<state>active</state>");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper
|
|
||||||
private String resource(String resource) {
|
|
||||||
return Constants.root_mapping + path + resource;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,231 +0,0 @@
|
||||||
package test.application;
|
|
||||||
|
|
||||||
import static app.Request.request;
|
|
||||||
import static org.gcube.smartgears.Constants.profile_file_path;
|
|
||||||
import static org.gcube.smartgears.lifecycle.application.ApplicationState.active;
|
|
||||||
import static org.gcube.smartgears.lifecycle.application.ApplicationState.failed;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Matchers.isA;
|
|
||||||
import static org.mockito.Mockito.doThrow;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import org.gcube.common.resources.gcore.Resource;
|
|
||||||
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
|
||||||
import org.gcube.informationsystem.publisher.exception.RegistryNotFoundException;
|
|
||||||
import org.gcube.smartgears.Constants;
|
|
||||||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
|
||||||
import org.gcube.smartgears.configuration.application.DefaultApplicationConfiguration;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.handlers.application.ApplicationEvent;
|
|
||||||
import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent.Start;
|
|
||||||
import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler;
|
|
||||||
import org.gcube.smartgears.handlers.application.RequestHandler;
|
|
||||||
import org.gcube.smartgears.persistence.LocalPersistence;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Matchers;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
import utils.TestUtils.Box;
|
|
||||||
|
|
||||||
public class StartupTest {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void teardown() {
|
|
||||||
app.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void succeedsWithDefaults() throws Exception {
|
|
||||||
|
|
||||||
|
|
||||||
app.useDefaultHandlers();
|
|
||||||
app.useDefaultExtensions();
|
|
||||||
|
|
||||||
ApplicationContext ctx = app.start();
|
|
||||||
|
|
||||||
assertEquals(active,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
//profile is shared in servlet context
|
|
||||||
assertEquals(ctx,ctx.application().getAttribute(Constants.context_attribute));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void stillStoresProfileWhenPublicationFails() throws Exception {
|
|
||||||
|
|
||||||
app.useDefaultHandlers();
|
|
||||||
|
|
||||||
ScopedPublisher failingPublisher = Mockito.mock(ScopedPublisher.class);
|
|
||||||
when(failingPublisher.create(any(Resource.class), Matchers.anyListOf(String.class))).thenThrow(new RegistryNotFoundException());
|
|
||||||
|
|
||||||
app.usePublisher(failingPublisher);
|
|
||||||
|
|
||||||
ApplicationContext ctx = app.start();
|
|
||||||
|
|
||||||
Thread.sleep(100); //a little bit of time for failure to propagate
|
|
||||||
|
|
||||||
//application has failed
|
|
||||||
assertEquals(failed,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
//profile has been created
|
|
||||||
File file = ctx.configuration().persistence().file(profile_file_path);
|
|
||||||
assertTrue(file.exists());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public void invokesLifecycleHandlers() {
|
|
||||||
|
|
||||||
ApplicationLifecycleHandler witness = mock(ApplicationLifecycleHandler.class);
|
|
||||||
|
|
||||||
app.handlers().set(witness);
|
|
||||||
|
|
||||||
//as we're using mocks, let us bypass JAXB configuration mechanisms
|
|
||||||
app.bypassHandlerDeployment();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
verify(witness).onEvent(any(ApplicationEvent.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public void registersRequestsHandlers() {
|
|
||||||
|
|
||||||
Box<Boolean> handlerIsInvoked = new Box<Boolean>();
|
|
||||||
|
|
||||||
RequestHandler witness = mock(RequestHandler.class);
|
|
||||||
|
|
||||||
app.handlers().set(witness);
|
|
||||||
|
|
||||||
app.bypassHandlerDeployment();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
app.send(request());
|
|
||||||
|
|
||||||
//invoked for request and response
|
|
||||||
verify(witness,times(2)).onEvent(isA(ApplicationEvent.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
//@Ignore //inexplicable sometimes fails as configuration is not removed
|
|
||||||
@Test
|
|
||||||
public void failsIfConfigurationIsInvalid() {
|
|
||||||
|
|
||||||
app.configuration().name(null).serviceClass(null).description(null).version(null).persistence(null);
|
|
||||||
|
|
||||||
ApplicationContext ctx = app.start();
|
|
||||||
|
|
||||||
assertEquals(failed,ctx.lifecycle().state());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void failsIfHandlerFails() throws Throwable {
|
|
||||||
|
|
||||||
ApplicationLifecycleHandler failingHandler = mock(ApplicationLifecycleHandler.class);
|
|
||||||
doThrow(new RuntimeException("simulated handler failure")).when(failingHandler).onEvent(isA(Start.class));
|
|
||||||
|
|
||||||
app.handlers().set(failingHandler);
|
|
||||||
|
|
||||||
app.bypassHandlerDeployment();
|
|
||||||
|
|
||||||
ApplicationContext ctx = app.start();
|
|
||||||
|
|
||||||
assertEquals(failed,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canUseExternalConfiguration() {
|
|
||||||
|
|
||||||
app.asExternal();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
assertTrue(app.isActive());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canUseMergedConfiguration() {
|
|
||||||
|
|
||||||
ApplicationConfiguration config = new DefaultApplicationConfiguration();
|
|
||||||
config.persistence(new LocalPersistence(new File(".").getAbsolutePath()));
|
|
||||||
|
|
||||||
ApplicationContext context = app.start();
|
|
||||||
|
|
||||||
assertTrue(app.isActive());
|
|
||||||
|
|
||||||
app.withExternal(config);
|
|
||||||
|
|
||||||
assertEquals(config.persistence(),context.configuration().persistence());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void failsIfAllStartScopesAreInvalid() throws Exception {
|
|
||||||
|
|
||||||
ApplicationConfiguration config = new DefaultApplicationConfiguration();
|
|
||||||
|
|
||||||
//config.startScopes("bad/scope","even/badder");
|
|
||||||
|
|
||||||
app.useDefaultHandlers();
|
|
||||||
|
|
||||||
ApplicationContext context = app.start();
|
|
||||||
|
|
||||||
app.withExternal(config);
|
|
||||||
|
|
||||||
assertEquals(failed,context.lifecycle().state());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canStartInVreScope() throws Exception {
|
|
||||||
|
|
||||||
ApplicationConfiguration config = new DefaultApplicationConfiguration();
|
|
||||||
|
|
||||||
//tring vre = "/"+app.containerConfiguration().infrastructure()+"/"+app.containerConfiguration().startVOs().get(0)+"/vre";
|
|
||||||
|
|
||||||
//config.startScopes(vre,"/bad/scope");
|
|
||||||
|
|
||||||
app.useDefaultHandlers();
|
|
||||||
|
|
||||||
ApplicationContext context = app.start();
|
|
||||||
|
|
||||||
app.withExternal(config);
|
|
||||||
|
|
||||||
assertEquals(active,context.lifecycle().state());
|
|
||||||
|
|
||||||
//Set<String> runningScopes = new HashSet<>(context.profile(GCoreEndpoint.class).scopes().asCollection());
|
|
||||||
|
|
||||||
//assertEquals(singleton(vre),runningScopes);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test(expected=RuntimeException.class)
|
|
||||||
public void failsIfConfigurationIsMissing() {
|
|
||||||
|
|
||||||
app.bypassConfigurationDeployment();
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package test.container;
|
|
||||||
|
|
||||||
import java.io.StringWriter;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
|
|
||||||
import org.ini4j.Ini;
|
|
||||||
import org.ini4j.Profile.Section;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ConfigurationTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void containerConfigurationBinds() throws Exception {
|
|
||||||
|
|
||||||
ContainerConfiguration bound = ContainerConfiguration
|
|
||||||
.load(ConfigurationTest.class.getResourceAsStream("/test-configuration.ini"));
|
|
||||||
|
|
||||||
bound.validate();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void iniStore() throws Exception {
|
|
||||||
Ini ini = new Ini();
|
|
||||||
|
|
||||||
// lets add a section, it will create needed intermediate sections as well
|
|
||||||
ini.add("root/child/sub");
|
|
||||||
|
|
||||||
Section rsec = ini.get("root");
|
|
||||||
rsec.add("test", "team");
|
|
||||||
Section csec = rsec.getChild("child");
|
|
||||||
csec.add("testchild", "pappo");
|
|
||||||
Section ssec = csec.getChild("sub");
|
|
||||||
ssec.add("testSec", "pippo");
|
|
||||||
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
ini.store(sw);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package test.container;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.context.container.ContainerContext;
|
|
||||||
import org.gcube.smartgears.lifecycle.application.ApplicationState;
|
|
||||||
import org.gcube.smartgears.lifecycle.container.ContainerState;
|
|
||||||
import org.gcube.smartgears.managers.ContainerManager;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class ContainerLifecycleTest {
|
|
||||||
|
|
||||||
|
|
||||||
SomeApp app;
|
|
||||||
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
app = new SomeApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void teardown() {
|
|
||||||
app.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void containerGoesToPartActiveWhenAppFails() {
|
|
||||||
|
|
||||||
|
|
||||||
ApplicationContext actx = app.start();
|
|
||||||
|
|
||||||
ContainerContext ctx = actx.container();
|
|
||||||
|
|
||||||
assertEquals(ContainerState.active,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
actx.lifecycle().moveTo(ApplicationState.failed);
|
|
||||||
|
|
||||||
assertEquals(ContainerState.partActive,ctx.lifecycle().state());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void containerGoesToPartActiveWhenAppStops() {
|
|
||||||
|
|
||||||
ApplicationContext actx = app.start();
|
|
||||||
|
|
||||||
ContainerContext ctx = actx.container();
|
|
||||||
|
|
||||||
assertEquals(ContainerState.active,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
actx.lifecycle().moveTo(ApplicationState.stopped);
|
|
||||||
|
|
||||||
assertEquals(ContainerState.partActive,ctx.lifecycle().state());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//used interactively to study shutdown
|
|
||||||
@Ignore
|
|
||||||
@Test
|
|
||||||
public void containerShutsdown() throws Exception {
|
|
||||||
|
|
||||||
ApplicationContext actx = app.start();
|
|
||||||
|
|
||||||
ContainerContext ctx = actx.container();
|
|
||||||
|
|
||||||
assertEquals(ContainerState.active,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
ContainerManager.instance.stop(true);
|
|
||||||
app.stop();
|
|
||||||
|
|
||||||
Thread.sleep(10000);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
package test.container;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.*;
|
|
||||||
import static org.gcube.smartgears.Constants.*;
|
|
||||||
import static org.gcube.smartgears.lifecycle.container.ContainerState.*;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.gcube.common.events.Observes;
|
|
||||||
import org.gcube.common.resources.gcore.HostingNode;
|
|
||||||
import org.gcube.common.resources.gcore.Resources;
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.gcube.smartgears.context.container.ContainerContext;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class ProfileManagementTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void createsStoresAndPublishesAValidProfile() throws Exception {
|
|
||||||
|
|
||||||
ContainerContext ctx = startAppAndGetContainerContext();
|
|
||||||
|
|
||||||
HostingNode node = ctx.profile();
|
|
||||||
|
|
||||||
assertNotNull(node);
|
|
||||||
|
|
||||||
//assert profile has been created
|
|
||||||
File profile = ctx.configuration().persistence().file(container_profile_file_path);
|
|
||||||
assertTrue(profile.exists());
|
|
||||||
|
|
||||||
assertFalse(node.scopes().isEmpty());
|
|
||||||
|
|
||||||
Resources.validate(node);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loadsAndUpdatesProfile() throws Exception {
|
|
||||||
|
|
||||||
startAppAndGetContainerContext();
|
|
||||||
|
|
||||||
SomeApp runtwice = new SomeApp();
|
|
||||||
|
|
||||||
runtwice.dirtyRun();
|
|
||||||
|
|
||||||
ContainerContext ctx = runtwice.start().container();
|
|
||||||
|
|
||||||
assertNotNull(ctx.profile());
|
|
||||||
|
|
||||||
HostingNode node = ctx.profile();
|
|
||||||
|
|
||||||
Resources.validate(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void periodicallyUpdatesAndPublishesProfile() throws Exception {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
//app.containerConfiguration().publicationFrequency(1);
|
|
||||||
|
|
||||||
ContainerContext ctx = app.start().container();
|
|
||||||
|
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
|
||||||
|
|
||||||
assertEquals(active,ctx.lifecycle().state());
|
|
||||||
|
|
||||||
ctx.events().subscribe(new Object() {
|
|
||||||
|
|
||||||
@Observes
|
|
||||||
void profileHasChangedAfterPeriodicUpdate(HostingNode ignore) {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!latch.await(4,TimeUnit.SECONDS))
|
|
||||||
fail();
|
|
||||||
|
|
||||||
ctx.lifecycle().moveTo(stopped); //should stop periodic updates
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ContainerContext startAppAndGetContainerContext() {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
ApplicationContext appCtx = app.start();
|
|
||||||
|
|
||||||
return appCtx.container();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package test.container;
|
|
||||||
|
|
||||||
import static org.gcube.smartgears.Constants.*;
|
|
||||||
import static org.gcube.smartgears.lifecycle.container.ContainerState.*;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import org.gcube.smartgears.context.application.ApplicationContext;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import app.SomeApp;
|
|
||||||
|
|
||||||
public class StartupTest {
|
|
||||||
|
|
||||||
SomeApp app = new SomeApp();
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void teardown() {
|
|
||||||
app.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=RuntimeException.class)
|
|
||||||
public void failsIfHomeIsNotConfigured() {
|
|
||||||
|
|
||||||
System.clearProperty(ghn_home_property);
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
assertFalse(app.isActive());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=RuntimeException.class)
|
|
||||||
public void failsIfInstallationFolderIsInvalid() {
|
|
||||||
|
|
||||||
System.setProperty(ghn_home_property,"foo");
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
assertFalse(app.isActive());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=RuntimeException.class)
|
|
||||||
public void failsIfConfigurationIsInvalid() {
|
|
||||||
|
|
||||||
//app.containerConfiguration().hostname(null);
|
|
||||||
|
|
||||||
app.start();
|
|
||||||
|
|
||||||
assertFalse(app.isActive());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void leavesContainerToActive() {
|
|
||||||
|
|
||||||
ApplicationContext ctx = app.start();
|
|
||||||
|
|
||||||
assertEquals(active,ctx.container().lifecycle().state());
|
|
||||||
|
|
||||||
assertTrue(app.isActive());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
[node]
|
||||||
|
; mandatory
|
||||||
|
; optional fields: mode (=online), publication-frequency-seconds (=60), authorizeChildrenContext (=false)
|
||||||
|
mode = online
|
||||||
|
hostname = dlib29.isti.cnr.it
|
||||||
|
protocol= http
|
||||||
|
port = 8080
|
||||||
|
infrastructure = gcube
|
||||||
|
authorizeChildrenContext = true
|
||||||
|
publicationFrequencyInSeconds = 60
|
||||||
|
|
||||||
|
[properties]
|
||||||
|
; not mandatory
|
||||||
|
SmartGearsDistribution = 0.0.1
|
||||||
|
SmartGearsDistributionBundle = UnBundled
|
||||||
|
|
||||||
|
[site]
|
||||||
|
; mandatory
|
||||||
|
; optional fields: latitude, logitude
|
||||||
|
country = it
|
||||||
|
location = rome
|
||||||
|
|
||||||
|
;[proxy]
|
||||||
|
; not mandatory
|
||||||
|
;protocol = https
|
||||||
|
;hostname = proxy
|
||||||
|
;port = 80
|
||||||
|
|
||||||
|
[authorization]
|
||||||
|
; mandatory
|
||||||
|
; optional fields: provider factory (=org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory)
|
||||||
|
factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory
|
||||||
|
credentials.class = org.gcube.smartgears.security.SimpleCredentials
|
||||||
|
credentials.clientID = testClient
|
||||||
|
credentials.secret = testSecret
|
||||||
|
credentials.endpoint = testSecret
|
||||||
|
|
||||||
|
;[persistence]
|
||||||
|
; not mandatory (default is LocalPersistence writing in the ghn home)
|
||||||
|
;class = utils.PersistenceWriterTest
|
||||||
|
;location = /tmp
|
|
@ -28,11 +28,12 @@ port = 80
|
||||||
|
|
||||||
[authorization]
|
[authorization]
|
||||||
; mandatory
|
; mandatory
|
||||||
; optional fields: provider (=org.gcube.smartgears.security.DefaultAuthorizationProvider)
|
; optional fields: factory provider (=org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory)
|
||||||
provider = org.gcube.smartgears.security.DefaultAuthorizationProvider
|
factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory
|
||||||
credentials.class = org.gcube.smartgears.security.SimpleCredentials
|
credentials.class = org.gcube.smartgears.security.SimpleCredentials
|
||||||
credentials.clientID = testClient
|
credentials.clientID = testClient
|
||||||
credentials.secret = testSecret
|
credentials.secret = testSecret
|
||||||
|
credentials.enpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
|
||||||
|
|
||||||
[persistence]
|
[persistence]
|
||||||
; not mandatory (default is LocalPersistence writing in the ghn home)
|
; not mandatory (default is LocalPersistence writing in the ghn home)
|
||||||
|
|
Loading…
Reference in New Issue