common-smartgears/src/main/java/org/gcube/smartgears/configuration/container/ContainerConfiguration.java

358 lines
9.4 KiB
Java

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;
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.common.validator.annotations.NotEmpty;
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.
*
* @author Fabio Simeoni
* @author Luca Frosini (ISTI - CNR)
*/
public class ContainerConfiguration {
@NotNull @IsValid
private BaseConfiguration baseConfiguration;
@IsValid
private Map<String,String> properties = new HashMap<String, String>();
@NotNull @IsValid
private Site site;
@IsValid
private ProxyAddress proxy;
@NotEmpty @NotNull
private String accountingFallbackLocation;
@XmlTransient
private Set<String> allowedContext = new HashSet<String>();
private List<ApplicationConfiguration> apps = new ArrayList<ApplicationConfiguration>();
@NotNull @IsValid
private PersistenceWriter persistenceManager;
@NotNull @IsValid
private AuthorizationProvider authorizationProvider;
/**
* Returns the management mode for the container.
* @return the management mode
*/
public Mode mode() {
return baseConfiguration.getMode();
}
/**
* Returns the application configurations included in this configuration.
* @return the application configurations
*/
public List<ApplicationConfiguration> apps() {
return apps;
}
/**
* Returns the configuration of an application with a given context path.
* @param context the context path
* @return the application configuration
*/
public ApplicationConfiguration app(String context) {
for (ApplicationConfiguration app : apps)
if (context.equals(app.context()))
return app;
return null;
}
/**
* Adds the configuration of an application to this configuration.
* @param app the application configuration
* @return this configuration
*/
public synchronized ContainerConfiguration app(ApplicationConfiguration app) {
int indexToRemove =-1;
int index =0;
for (ApplicationConfiguration application : apps){
if (app.context().equals(application.context()))
indexToRemove = index;
index++;
}
if(indexToRemove!=-1)
apps.remove(indexToRemove);
apps.add(app);
return this;
}
/**
* Returns the geographical site of the container.
* @return the site
*/
public Site site() {
return site;
}
/**
* Returns the infrastructure in which the container is running.
* @return the infrastructure
*/
public String infrastructure() {
return baseConfiguration.getInfrastructure();
}
/**
* Returns the host name of the container.
* @return the host name;
*/
public String hostname() {
return baseConfiguration.getHostname();
}
/**
* Returns the port at which the container is listening for requests.
* @return the port
*/
public int port() {
return baseConfiguration.getPort();
}
/**
* Returns the port at which the container is listening for requests.
* @return the port
*/
public String protocol() {
return baseConfiguration.getProtocol();
}
public boolean authorizeChildrenContext() {
return baseConfiguration.isAuthorizeChildrenContext();
}
/**
* Returns the credentials.
* @return the credentials
*/
public AuthorizationProvider authorizationProvider() {
return authorizationProvider;
}
/**
* Returns the proxy of the container.
* @return the proxy
*/
public ProxyAddress proxy() {
return proxy;
}
/**
* Returns the persistence manager of the container.
* @return the manager
*/
public PersistenceWriter persistence() {
return persistenceManager;
}
/**
* Returns the persistence manager of the container.
* @return the manager
*/
public String accountingFallbackLocation() {
return accountingFallbackLocation;
}
/**
* Returns the configuration properties of the container.
* @return the properties
*/
public Map<String,String> properties() {
return Collections.unmodifiableMap(properties);
}
/**
* Returns the publication frequency for the container's profile.
* @return the frquency;
*/
public long publicationFrequency() {
return baseConfiguration.getPublicationFrequencyInSeconds();
}
public Set<String> allowedContexts() {
return allowedContext;
}
public void allowedContexts(Set<String> allowedContexts) {
this.allowedContext = allowedContexts;
}
/**
* Validates this configuration
*
* @throws IllegalStateException if the configuration is invalid
*/
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);
}
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);
}
}
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;
}
}
}