parent
a285c20b38
commit
f54efc1e4e
|
@ -38,12 +38,6 @@ public class Constants {
|
|||
|
||||
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.
|
||||
|
@ -62,24 +56,11 @@ public class Constants {
|
|||
public static final long default_container_publication_frequency_in_seconds = 60;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The application configuration resource path.
|
||||
*/
|
||||
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.
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
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.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -12,7 +15,11 @@ import javax.xml.bind.JAXBContext;
|
|||
import javax.xml.bind.JAXBException;
|
||||
|
||||
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.
|
||||
|
@ -54,25 +61,27 @@ public class ApplicationConfigurationBinder {
|
|||
* @return the handlers
|
||||
* @throws RuntimeException if the serialisation is invalid
|
||||
*/
|
||||
public ApplicationHandlers bindHandlers(InputStream stream) {
|
||||
public ApplicationHandlers bindHandlers(ClassLoader classLoader) {
|
||||
|
||||
//collects handler classes
|
||||
Set<Class<?>> classes = scanForHandlers();
|
||||
|
||||
try {
|
||||
|
||||
JAXBContext ctx = JAXBContext.newInstance(classes.toArray(new Class<?>[0]));
|
||||
|
||||
return (ApplicationHandlers) ctx.createUnmarshaller().unmarshal(stream);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
|
||||
throw unchecked(e);
|
||||
|
||||
}
|
||||
finally {
|
||||
closeSafely(stream);
|
||||
}
|
||||
List<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();
|
||||
|
||||
//ADDING BASE Handler (order is important)
|
||||
requestHandlers.add(new RequestValidator());
|
||||
requestHandlers.add(new RequestAccounting());
|
||||
|
||||
//TODO scan RequestHAndler form classloader
|
||||
|
||||
|
||||
List<ApplicationLifecycleHandler> lifecycleHandlers = new LinkedList<ApplicationLifecycleHandler>();
|
||||
|
||||
//ADDING BASE Handler (order is important)
|
||||
lifecycleHandlers.add(new ProfileManager());
|
||||
|
||||
|
||||
//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 {
|
||||
|
||||
|
@ -146,4 +134,8 @@ public class ApplicationConfigurationBinder {
|
|||
|
||||
return scanned;
|
||||
}
|
||||
|
||||
public void scanForApplicationHandlers(ClassLoader currentClassLoader) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
package org.gcube.smartgears.configuration.application;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
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.ApplicationLifecycleHandler;
|
||||
import org.gcube.smartgears.handlers.application.RequestHandler;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* The {@link ApplicationHandler}s that manage the application.
|
||||
|
@ -23,24 +13,24 @@ import org.w3c.dom.Element;
|
|||
* @author Fabio Simeoni
|
||||
*
|
||||
*/
|
||||
@XmlRootElement(name="handlers")
|
||||
public class ApplicationHandlers {
|
||||
|
||||
|
||||
@XmlElement(name="lifecycle") @IsValid
|
||||
private LifecycleHandlers lifecycleHandlers = new LifecycleHandlers();
|
||||
private List<ApplicationLifecycleHandler> lifecycleHandlers = new LinkedList<ApplicationLifecycleHandler>();
|
||||
|
||||
@XmlElement(name="request") @IsValid
|
||||
private RequestHandlers requestHandlers = new RequestHandlers();
|
||||
private List<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();
|
||||
|
||||
public ApplicationHandlers() {}
|
||||
public ApplicationHandlers(List<ApplicationLifecycleHandler> lifecycleHandlers, List<RequestHandler> requestHandlers) {
|
||||
this.lifecycleHandlers = lifecycleHandlers;
|
||||
this.requestHandlers = requestHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ApplicationLifecycleHandler}s for the service.
|
||||
* @return the lifecycle handlers
|
||||
*/
|
||||
public List<ApplicationLifecycleHandler> lifecycleHandlers() {
|
||||
return lifecycleHandlers.values;
|
||||
return lifecycleHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,8 +38,8 @@ public class ApplicationHandlers {
|
|||
* @param handlers the lifecycle handlers
|
||||
* @return this configuration
|
||||
*/
|
||||
public ApplicationHandlers set(ApplicationLifecycleHandler ... handlers) {
|
||||
this.lifecycleHandlers = new LifecycleHandlers(Arrays.asList(handlers));
|
||||
public ApplicationHandlers setLifecycleHandlers(List<ApplicationLifecycleHandler> handlers) {
|
||||
this.lifecycleHandlers = handlers;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -58,7 +48,7 @@ public class ApplicationHandlers {
|
|||
* @return the lifetime handlers
|
||||
*/
|
||||
public List<RequestHandler> requestHandlers() {
|
||||
return requestHandlers.values;
|
||||
return requestHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,75 +56,11 @@ public class ApplicationHandlers {
|
|||
* @param handlers the request handlers
|
||||
* @return this configuration
|
||||
*/
|
||||
public ApplicationHandlers set(RequestHandler ... handlers) {
|
||||
this.requestHandlers = new RequestHandlers(Arrays.asList(handlers));
|
||||
public ApplicationHandlers setRequetHandlers(List<RequestHandler> handlers) {
|
||||
this.requestHandlers = handlers;
|
||||
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){
|
||||
List<ApplicationLifecycleHandler> lifecycles = other.lifecycleHandlers();
|
||||
|
|
|
@ -85,8 +85,6 @@ public class BaseConfiguration {
|
|||
this.infrastructure = infrastructure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
package org.gcube.smartgears.configuration.container;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.ProxyAddress;
|
||||
import org.gcube.smartgears.configuration.application.ApplicationConfiguration;
|
||||
import org.gcube.smartgears.persistence.LocalPersistence;
|
||||
import org.gcube.smartgears.persistence.PersistenceWriter;
|
||||
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.
|
||||
|
@ -69,6 +59,35 @@ public class ContainerConfiguration {
|
|||
@NotNull @IsValid
|
||||
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.
|
||||
* @return the management mode
|
||||
|
@ -243,116 +262,14 @@ public class ContainerConfiguration {
|
|||
|
||||
}
|
||||
|
||||
public static ContainerConfiguration load(InputStream stream) {
|
||||
try {
|
||||
Ini configurator = new Ini(stream);
|
||||
ContainerConfiguration conf = new ContainerConfiguration();
|
||||
|
||||
Section nodeSection = configurator.get("node");
|
||||
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);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContainerConfiguration [baseConfiguration=" + baseConfiguration + ", properties=" + properties
|
||||
+ ", site=" + site + ", proxy=" + proxy + ", accountingFallbackLocation=" + accountingFallbackLocation
|
||||
+ ", persistenceManager=" + persistenceManager.getClass().getSimpleName()
|
||||
+ ", authorizationProvider=" + authorizationProvider.getClass().getSimpleName() + "]";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import static org.gcube.smartgears.utils.Utils.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.gcube.smartgears.configuration.ProxyAddress;
|
||||
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.ini4j.Ini;
|
||||
import org.ini4j.Profile.Section;
|
||||
|
||||
/**
|
||||
* Binds {@link ContainerConfiguration}s to and from XML serialisations.
|
||||
|
@ -22,31 +30,117 @@ import org.gcube.smartgears.utils.Utils;
|
|||
*/
|
||||
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 {
|
||||
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;
|
||||
|
||||
} catch (JAXBException e) {
|
||||
|
||||
throw new RuntimeException("invalid container configuration", e);
|
||||
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.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
|
||||
* @throws RuntimeException if the serialisation is invalid
|
||||
*/
|
||||
public ContainerHandlers bindHandlers(InputStream stream) {
|
||||
public List<ContainerHandler> bindHandlers(ClassLoader classloader) {
|
||||
|
||||
//collects handler classes
|
||||
Set<Class<?>> classes = scanForConfigurationElements();
|
||||
|
||||
try {
|
||||
|
||||
JAXBContext ctx = JAXBContext.newInstance(classes.toArray(new Class<?>[0]));
|
||||
|
||||
return (ContainerHandlers) ctx.createUnmarshaller().unmarshal(stream);
|
||||
|
||||
} catch (JAXBException e) {
|
||||
|
||||
throw unchecked(e);
|
||||
|
||||
}
|
||||
LinkedList<ContainerHandler> handlers = new LinkedList<ContainerHandler>();
|
||||
|
||||
//ADDING BASE Handler (order is important)
|
||||
handlers.add(new AccountingManager());
|
||||
handlers.add(new ProfileContainerManager());
|
||||
|
||||
handlers.addAll(scanForContainerHadlers(classloader));
|
||||
|
||||
return handlers;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Set<Class<?>> scanForConfigurationElements() throws RuntimeException {
|
||||
|
||||
@SuppressWarnings("all")
|
||||
ServiceLoader<ContainerHandler> handlerLoader = (ServiceLoader) ServiceLoader.load(ContainerHandler.class);
|
||||
|
||||
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;
|
||||
private List<? extends ContainerHandler> scanForContainerHadlers(ClassLoader classloader) throws RuntimeException {
|
||||
|
||||
//TODO: scan for Container Handler
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.gcube.accounting.persistence.AccountingPersistenceFactory;
|
||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||
import org.gcube.smartgears.handlers.container.ContainerLifecycleEvent;
|
||||
|
@ -16,7 +14,6 @@ import org.slf4j.LoggerFactory;
|
|||
/**
|
||||
* @author Luca Frosini (ISTI - CNR)
|
||||
*/
|
||||
@XmlRootElement(name = accounting_management)
|
||||
public class AccountingManager extends ContainerHandler {
|
||||
|
||||
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.concurrent.ScheduledFuture;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.gcube.common.events.Observes;
|
||||
import org.gcube.common.resources.gcore.HostingNode;
|
||||
import org.gcube.smartgears.configuration.Mode;
|
||||
|
@ -52,10 +50,9 @@ import org.slf4j.LoggerFactory;
|
|||
* @author Fabio Simeoni
|
||||
* @see ProfileBuilder
|
||||
*/
|
||||
@XmlRootElement(name = profile_management)
|
||||
public class ProfileManager extends ContainerHandler {
|
||||
public class ProfileContainerManager extends ContainerHandler {
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(ProfileManager.class);
|
||||
private static Logger log = LoggerFactory.getLogger(ProfileContainerManager.class);
|
||||
|
||||
private ContainerContext context;
|
||||
|
|
@ -83,7 +83,6 @@ public class ApplicationManager {
|
|||
registerObservers();
|
||||
|
||||
ApplicationHandlers handlers = provider().handlersFor(context);
|
||||
handlers.validate();
|
||||
|
||||
ApplicationExtensions extensions = provider().extensionsFor(context);
|
||||
extensions.validate();
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Set;
|
|||
import org.gcube.common.events.Observes;
|
||||
import org.gcube.common.events.Observes.Kind;
|
||||
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.container.ContainerContext;
|
||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||
|
@ -61,18 +60,15 @@ public class ContainerManager {
|
|||
|
||||
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);
|
||||
|
||||
log.trace("loading keys for starting token ...");
|
||||
//loadKeyForToken(context.configuration().startTokens());
|
||||
log.trace("keys loaded for starting token ...");
|
||||
|
||||
|
||||
return context;
|
||||
}
|
||||
catch(RuntimeException e) {
|
||||
|
@ -103,10 +99,9 @@ public class ContainerManager {
|
|||
//List<String> tokensToRemove = new ArrayList<String>();
|
||||
context.configuration().validate();
|
||||
Set<String> foundContexts;
|
||||
|
||||
|
||||
|
||||
try {
|
||||
foundContexts = context.configuration().allowedContexts();
|
||||
foundContexts = context.configuration().authorizationProvider().getAllowedContexts();
|
||||
} catch (Exception e) {
|
||||
log.error("error authorizing container",e);
|
||||
throw new RuntimeException("error authorizing container, moving the container to failed",e);
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
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.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.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.ghn_home_env;
|
||||
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.profile_file_path;
|
||||
|
||||
|
@ -19,21 +14,13 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.gcube.common.events.Hub;
|
||||
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.ScopedPublisher;
|
||||
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.container.ContainerConfiguration;
|
||||
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.SmartGearsConfigurationBinder;
|
||||
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.container.ContainerContext;
|
||||
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.container.ContainerLifecycle;
|
||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||
|
@ -78,7 +65,7 @@ public class DefaultProvider implements Provider {
|
|||
protected DefaultProvider(File configFile) {
|
||||
this.configFile = configFile;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected DefaultProvider(){};
|
||||
|
||||
|
@ -87,18 +74,6 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
if(containerContext==null){
|
||||
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();
|
||||
|
||||
|
@ -128,17 +103,11 @@ public class DefaultProvider implements Provider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ContainerHandlers containerHandlers() {
|
||||
public List<ContainerHandler> containerHandlers() {
|
||||
|
||||
try {
|
||||
|
||||
//TODO retrieve handler classes
|
||||
|
||||
if (config == null)
|
||||
throw new IllegalStateException("invalid distribution: cannot find " + container_handlers_file_path);
|
||||
|
||||
ContainerConfigurationBinder binder = new ContainerConfigurationBinder();
|
||||
ContainerHandlers defaultHandlers = binder.bindHandlers(config);
|
||||
|
||||
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (currentClassLoader.getParent()!=null && !currentClassLoader.getParent().equals(ClassLoader.getSystemClassLoader())){
|
||||
|
@ -146,35 +115,7 @@ public class DefaultProvider implements Provider {
|
|||
currentClassLoader = currentClassLoader.getParent();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
List<ContainerHandler> defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||
|
||||
return defaultHandlers;
|
||||
|
||||
|
@ -250,15 +191,10 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
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();
|
||||
|
||||
ApplicationHandlers defaultHandlers = binder.bindHandlers(defaultHandlersStream);
|
||||
|
||||
|
||||
//searching for smartegars related application handlers in the common classloader
|
||||
ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
@ -267,40 +203,8 @@ public class DefaultProvider implements Provider {
|
|||
currentClassLoader = currentClassLoader.getParent();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
ApplicationHandlers defaultHandlers = binder.bindHandlers(currentClassLoader);
|
||||
|
||||
return defaultHandlers;
|
||||
|
||||
|
||||
|
@ -393,9 +297,9 @@ public class DefaultProvider implements Provider {
|
|||
private ContainerConfiguration containerConfiguration() {
|
||||
|
||||
if (configFile==null) {
|
||||
|
||||
|
||||
String home = Utils.home();
|
||||
|
||||
|
||||
if (home == null)
|
||||
throw new IllegalStateException("invalid node configuration: the environment variable " + ghn_home_env
|
||||
+ " 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);
|
||||
|
||||
|
||||
|
||||
log.trace("reading container configuration @ {} ", configFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
@ -416,11 +320,11 @@ public class DefaultProvider implements Provider {
|
|||
|
||||
ContainerConfiguration configuration;
|
||||
try (InputStream stream = new FileInputStream(configFile)){
|
||||
configuration= ContainerConfiguration.load(stream);
|
||||
configuration= new ContainerConfigurationBinder().load(stream);
|
||||
}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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package org.gcube.smartgears.provider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.gcube.informationsystem.publisher.ScopedPublisher;
|
||||
import org.gcube.smartgears.configuration.application.ApplicationExtensions;
|
||||
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.context.application.ApplicationContext;
|
||||
import org.gcube.smartgears.context.container.ContainerContext;
|
||||
import org.gcube.smartgears.handlers.container.ContainerHandler;
|
||||
import org.gcube.smartgears.security.AuthorizationProvider;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +39,7 @@ public interface Provider {
|
|||
* Returns the handlers associated with the container.
|
||||
* @return the handlers
|
||||
*/
|
||||
ContainerHandlers containerHandlers();
|
||||
List<ContainerHandler> containerHandlers();
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,5 @@ import java.util.Set;
|
|||
|
||||
public interface AuthorizationProvider {
|
||||
|
||||
void connect(Credentials credentials) throws Exception;
|
||||
|
||||
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
|
||||
String secret;
|
||||
|
||||
@NotNull @NotEmpty
|
||||
String endpoint;
|
||||
|
||||
public String getClientID() {
|
||||
return clientID;
|
||||
|
@ -17,6 +20,14 @@ public class SimpleCredentials implements Credentials{
|
|||
|
||||
public void setClientID(String clientID) {
|
||||
this.clientID = clientID;
|
||||
}
|
||||
|
||||
public String getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
public void setEndpoint(String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
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.HashSet;
|
||||
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.TokenResponse;
|
||||
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.LoggerFactory;
|
||||
|
||||
|
@ -18,20 +21,20 @@ public class DefaultAuthorizationProvider implements AuthorizationProvider {
|
|||
|
||||
private static Logger LOG = LoggerFactory.getLogger(DefaultAuthorizationProvider.class);
|
||||
|
||||
private SimpleCredentials credentials;
|
||||
|
||||
private KeycloakClient client = KeycloakClientFactory.newInstance();
|
||||
|
||||
@Override
|
||||
public void connect(Credentials credentials) {
|
||||
this.credentials = (SimpleCredentials)credentials;
|
||||
private SimpleCredentials credentials;
|
||||
|
||||
public DefaultAuthorizationProvider(SimpleCredentials credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getAllowedContexts() {
|
||||
Set<String> contexts = new HashSet<String>();
|
||||
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();
|
||||
for (String context : resourceAccess.keySet()) {
|
||||
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]
|
||||
; mandatory
|
||||
; optional fields: provider (=org.gcube.smartgears.security.DefaultAuthorizationProvider)
|
||||
provider = org.gcube.smartgears.security.DefaultAuthorizationProvider
|
||||
; optional fields: factory provider (=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.enpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
|
||||
|
||||
[persistence]
|
||||
; not mandatory (default is LocalPersistence writing in the ghn home)
|
||||
|
|
Loading…
Reference in New Issue