@ -14,12 +14,11 @@ import java.io.File;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.io.ObjectInputStream ;
import java.net.URL ;
import java.util.ArrayList ;
import java.util.Collection ;
import java.util.List ;
import java.util.Set ;
import java.util.UUID ;
import java.util.stream.Collectors ;
import javax.servlet.ServletContext ;
@ -48,14 +47,14 @@ import org.gcube.smartgears.publishing.SmartgearsProfilePublisher;
import org.gcube.smartgears.security.AuthorizationProvider ;
import org.gcube.smartgears.security.AuthorizationProviderFactory ;
import org.gcube.smartgears.utils.Utils ;
import org.reflections.Reflections ;
import org.reflections.scanners.SubTypesScanner ;
import org.reflections.scanners.TypeAnnotationsScanner ;
import org.reflections.util.ClasspathHelper ;
import org.reflections.util.ConfigurationBuilder ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import io.github.classgraph.ClassGraph ;
import io.github.classgraph.ClassInfo ;
import io.github.classgraph.ClassInfoList ;
import io.github.classgraph.ScanResult ;
/ * *
* Default implementation of the { @link Provider } interface .
*
@ -67,8 +66,7 @@ public class DefaultProvider implements Provider {
private static Logger log = LoggerFactory . getLogger ( Provider . class ) ;
private ContainerContext containerContext ;
//TODO: do the same with applicationContext (with a map)
// TODO: do the same with applicationContext (with a map)
private File configFile = null ;
@ -78,13 +76,13 @@ public class DefaultProvider implements Provider {
List < Publisher > publishers ;
protected DefaultProvider ( ) { } ;
protected DefaultProvider ( ) {
} ;
@Override
public ContainerContext containerContext ( ) {
if ( containerContext = = null ) {
if ( containerContext = = null ) {
ContainerConfiguration configuration = containerConfiguration ( ) ;
Hub hub = new DefaultHub ( ) ;
@ -94,27 +92,29 @@ public class DefaultProvider implements Provider {
File file = configuration . persistence ( ) . file ( container_profile_file_path ) ;
String id = null ;
if ( file . exists ( ) ) {
if ( file . exists ( ) ) {
log . info ( "loading persisted state for container" ) ;
try ( ObjectInputStream ois = new ObjectInputStream ( new FileInputStream ( file ) ) ) {
id = ( String ) ois . readObject ( ) ;
} catch ( Exception e ) {
log . error ( "error loading persisted state, creating new uuid" , e ) ;
try ( ObjectInputStream ois = new ObjectInputStream ( new FileInputStream ( file ) ) ) {
id = ( String ) ois . readObject ( ) ;
} catch ( Exception e ) {
log . error ( "error loading persisted state, creating new uuid" , e ) ;
}
}
if ( id = = null ) {
}
if ( id = = null ) {
id = UUID . randomUUID ( ) . toString ( ) ;
log . info ( "container id created is {}" , id ) ;
log . info ( "container id created is {}" , id ) ;
}
}
AuthorizationProviderFactory < ? > authfactory = configuration . getauthorizationConfiguration ( ) . getAuthProviderFactory ( ) ;
AuthorizationProviderFactory < ? > authfactory = configuration . getauthorizationConfiguration ( )
. getAuthProviderFactory ( ) ;
Credentials credentials = configuration . getauthorizationConfiguration ( ) . getCredentials ( ) ;
AuthorizationProvider authProvider = authfactory . connect ( credentials ) ;
containerContext = new DefaultContainerContext ( id , configuration , hub , lifecycle , authProvider , new Properties ( ) ) ;
containerContext = new DefaultContainerContext ( id , configuration , hub , lifecycle , authProvider ,
new Properties ( ) ) ;
}
return containerContext ;
}
@ -127,12 +127,13 @@ public class DefaultProvider implements Provider {
ContainerConfigurationBinder binder = new ContainerConfigurationBinder ( ) ;
ClassLoader currentClassLoader = Thread . currentThread ( ) . getContextClassLoader ( ) ;
if ( currentClassLoader . getParent ( ) ! = null & & ! currentClassLoader . getParent ( ) . equals ( ClassLoader . getSystemClassLoader ( ) ) ) {
if ( currentClassLoader . getParent ( ) ! = null
& & ! currentClassLoader . getParent ( ) . equals ( ClassLoader . getSystemClassLoader ( ) ) ) {
log . trace ( "probably i'm in a webapp classloader" ) ;
currentClassLoader = currentClassLoader . getParent ( ) ;
}
List < ContainerHandler > defaultHandlers = binder . bindHandlers ( currentClassLoader ) ;
List < ContainerHandler > defaultHandlers = binder . bindHandlers ( currentClassLoader ) ;
return defaultHandlers ;
@ -150,34 +151,37 @@ public class DefaultProvider implements Provider {
ApplicationConfiguration embedded = configurationFor ( application ) ;
ApplicationConfiguration external = context . configuration ( ) . app ( application . getContextPath ( ) ) ;
//shouldn't happen: management shouldn't have started at all
if ( embedded = = null & & external = = null )
throw new AssertionError ( "application @ " + application . getContextPath ( ) + " is not distributed with "
+ configuration_file_path + " and there is no external configuration for it in " + container_configuraton_file_path ) ;
// shouldn't happen: management shouldn't have started at all
if ( embedded = = null & & external = = null )
throw new AssertionError ( "application @ " + application . getContextPath ( ) + " is not distributed with "
+ configuration_file_path + " and there is no external configuration for it in "
+ container_configuraton_file_path ) ;
// no embedded configuration
// no embedded configuration
if ( embedded = = null ) {
configuration = external ;
configuration = external ;
log . info ( "loaded configuration for application " + configuration . name ( ) + " from " + container_configuraton_file_path ) ;
}
else {
log . info ( "loaded configuration for application " + configuration . name ( ) + " from "
+ container_configuraton_file_path ) ;
} else {
configuration = embedded ;
if ( external = = null )
log . info ( "loaded configuration for application " + configuration . name ( ) + " from " + configuration_file_path ) ;
log . info ( "loaded configuration for application " + configuration . name ( ) + " from "
+ configuration_file_path ) ;
else {
configuration . merge ( external ) ;
log . info ( "loaded configuration for application " + configuration . name ( ) + " from " + configuration_file_path + " and " + container_configuraton_file_path ) ;
log . info ( "loaded configuration for application " + configuration . name ( ) + " from "
+ configuration_file_path + " and " + container_configuraton_file_path ) ;
}
}
}
ApplicationConfiguration bridgedConfiguration = new BridgedApplicationConfiguration ( context . configuration ( ) ,
configuration ) ;
@ -187,16 +191,16 @@ public class DefaultProvider implements Provider {
ApplicationLifecycle lifecycle = new ApplicationLifecycle ( hub , configuration . name ( ) ) ;
File file = bridgedConfiguration . persistence ( ) . file ( profile_file_path ) ;
String id = null ;
if ( file . exists ( ) ) {
String id = null ;
if ( file . exists ( ) ) {
log . info ( "loading persisted state for application {}" , application . getContextPath ( ) ) ;
try ( ObjectInputStream ois = new ObjectInputStream ( new FileInputStream ( file ) ) ) {
id = ( String ) ois . readObject ( ) ;
} catch ( Exception e ) {
log . error ( "error loading persisted state, creating new uuid" , e ) ;
try ( ObjectInputStream ois = new ObjectInputStream ( new FileInputStream ( file ) ) ) {
id = ( String ) ois . readObject ( ) ;
} catch ( Exception e ) {
log . error ( "error loading persisted state, creating new uuid" , e ) ;
}
}
if ( id = = null )
}
if ( id = = null )
id = UUID . randomUUID ( ) . toString ( ) ;
return new DefaultApplicationContext ( id , context , application , bridgedConfiguration , hub , lifecycle ,
@ -208,31 +212,29 @@ public class DefaultProvider implements Provider {
try {
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder ( ) ;
//searching for smartegars related application handlers in the common classloader
// searching for smartegars related application handlers in the common
// classloader
ClassLoader currentClassLoader = Thread . currentThread ( ) . getContextClassLoader ( ) ;
if ( currentClassLoader . getParent ( ) ! = null & & ! currentClassLoader . getParent ( ) . equals ( ClassLoader . getSystemClassLoader ( ) ) ) {
if ( currentClassLoader . getParent ( ) ! = null
& & ! currentClassLoader . getParent ( ) . equals ( ClassLoader . getSystemClassLoader ( ) ) ) {
log . trace ( "probably i'm in a webapp classloader" ) ;
currentClassLoader = currentClassLoader . getParent ( ) ;
}
ApplicationHandlers defaultHandlers = binder . bindHandlers ( currentClassLoader ) ;
return defaultHandlers ;
return defaultHandlers ;
} catch ( RuntimeException e ) {
throw new RuntimeException ( "cannot install handlers for application @ " + context . name ( ) + " (see cause) " , e ) ;
throw new RuntimeException ( "cannot install handlers for application @ " + context . name ( ) + " (see cause) " ,
e ) ;
}
}
@Override
public ApplicationExtensions extensionsFor ( ApplicationContext context ) {
@ -248,7 +250,8 @@ public class DefaultProvider implements Provider {
config = getClass ( ) . getResourceAsStream ( default_extensions_file_path ) ;
if ( config = = null )
throw new IllegalStateException ( "invalid distribution: cannot find " + default_extensions_file_path ) ;
throw new IllegalStateException (
"invalid distribution: cannot find " + default_extensions_file_path ) ;
} else
log . info ( "{} uses custom extensions @ {}" , context . name ( ) , extensions_file_path ) ;
@ -259,12 +262,12 @@ public class DefaultProvider implements Provider {
} catch ( RuntimeException e ) {
throw new RuntimeException ( "cannot install extensions for application @ " + context . name ( ) + " (see cause) " , e ) ;
throw new RuntimeException (
"cannot install extensions for application @ " + context . name ( ) + " (see cause) " , e ) ;
}
}
@Override
public SmartGearsConfiguration smartgearsConfiguration ( ) {
@ -297,7 +300,7 @@ public class DefaultProvider implements Provider {
InputStream config = application . getResourceAsStream ( configuration_file_path ) ;
if ( config = = null )
if ( config = = null )
return null ;
ApplicationConfigurationBinder binder = new ApplicationConfigurationBinder ( ) ;
@ -313,7 +316,7 @@ public class DefaultProvider implements Provider {
private ContainerConfiguration containerConfiguration ( ) {
if ( configFile = = null ) {
if ( configFile = = null ) {
String home = Utils . home ( ) ;
@ -324,22 +327,24 @@ public class DefaultProvider implements Provider {
File homeDir = new File ( home ) ;
if ( ! ( homeDir . exists ( ) & & homeDir . isDirectory ( ) & & homeDir . canRead ( ) & & homeDir . canWrite ( ) ) )
throw new IllegalStateException ( "invalid node configuration: home " + home + " does not exist or is not a directory or cannot be accessed in read/write mode" ) ;
configFile = new File ( homeDir , container_configuraton_file_path ) ;
throw new IllegalStateException ( "invalid node configuration: home " + home
+ " does not exist or is not a directory or cannot be accessed in read/write mode" ) ;
configFile = new File ( homeDir , container_configuraton_file_path ) ;
log . trace ( "reading container configuration @ {} " , configFile . getAbsolutePath ( ) ) ;
}
if ( ! ( configFile . exists ( ) & & configFile . canRead ( ) ) )
throw new IllegalStateException ( "invalid node configuration: file " + configFile . getAbsolutePath ( ) + " does not exist or cannot be accessed" ) ;
throw new IllegalStateException ( "invalid node configuration: file " + configFile . getAbsolutePath ( )
+ " does not exist or cannot be accessed" ) ;
ContainerConfiguration configuration ;
try ( InputStream stream = new FileInputStream ( configFile ) ) {
configuration = new ContainerConfigurationBinder ( ) . load ( stream ) ;
} catch ( Exception e ) {
throw new IllegalStateException ( "invalid node configuration: file " + configFile . getAbsolutePath ( ) + " is invalid" , e ) ;
try ( InputStream stream = new FileInputStream ( configFile ) ) {
configuration = new ContainerConfigurationBinder ( ) . load ( stream ) ;
} catch ( Exception e ) {
throw new IllegalStateException (
"invalid node configuration: file " + configFile . getAbsolutePath ( ) + " is invalid" , e ) ;
}
return configuration ;
@ -348,43 +353,56 @@ public class DefaultProvider implements Provider {
@Override
public synchronized List < Publisher > publishers ( ) {
if ( this . publishers = = null ) {
//retrieve from root class loader
Collection < URL > urls = ClasspathHelper . forClassLoader ( Thread . currentThread ( ) . getContextClassLoader ( ) ) ;
urls . removeIf ( url - > url . toString ( ) . endsWith ( ".so" ) | | url . toString ( ) . endsWith ( ".zip" ) ) ;
Set < Class < ? > > annotatedPublishers ;
try ( ScanResult result = new ClassGraph ( ) . enableClassInfo ( ) . enableAnnotationInfo ( )
. addClassLoader ( Thread . currentThread ( ) . getContextClassLoader ( ) ) . scan ( ) ) {
ClassInfoList classInfos = result . getClassesWithAnnotation ( SmartgearsProfilePublisher . class . getName ( ) ) ;
ConfigurationBuilder reflectionConf = new ConfigurationBuilder ( ) . addUrls ( urls ) . setScanners ( new TypeAnnotationsScanner ( ) , new SubTypesScanner ( ) ) ;
annotatedPublishers = classInfos . stream ( ) . map ( ClassInfo : : loadClass )
. filter ( c - > Publisher . class . isAssignableFrom ( c ) ) . collect ( Collectors . toSet ( ) ) ;
Reflections reflection = new Reflections ( reflectionConf ) ;
}
/ *
* Collection < URL > urls =
* ClasspathHelper . forClassLoader ( Thread . currentThread ( ) . getContextClassLoader ( )
* ) ; urls . removeIf ( url - > url . toString ( ) . endsWith ( ".so" ) | |
* url . toString ( ) . endsWith ( ".zip" ) ) ;
*
*
* ConfigurationBuilder reflectionConf = new
* ConfigurationBuilder ( ) . addUrls ( urls ) . setScanners ( new
* TypeAnnotationsScanner ( ) , new SubTypesScanner ( ) ) ;
*
* Reflections reflection = new Reflections ( reflectionConf ) ;
*
* = reflection . getTypesAnnotatedWith ( SmartgearsProfilePublisher . class ) ;
* /
Set < Class < ? > > annotatedPublishers = reflection . getTypesAnnotatedWith ( SmartgearsProfilePublisher . class ) ;
List < Publisher > foundPublishers = new ArrayList < Publisher > ( ) ;
for ( Class < ? > annotatedPublisher : annotatedPublishers ) {
if ( Publisher . class . isAssignableFrom ( annotatedPublisher ) )
try {
foundPublishers . add ( ( Publisher ) annotatedPublisher . newInstance ( ) ) ;
log . info ( "added class {} to publishers" , annotatedPublisher ) ;
} catch ( Exception e ) {
log . error ( "publisher class {} cannot be instantiated" , annotatedPublisher . getCanonicalName ( ) , e ) ;
}
else
log . warn ( "publisher class {} discarded, it doesn't implements Publisher class" , annotatedPublisher . getCanonicalName ( ) ) ;
for ( Class < ? > annotatedPublisher : annotatedPublishers ) {
try {
foundPublishers . add ( ( Publisher ) annotatedPublisher . getDeclaredConstructor ( ) . newInstance ( ) ) ;
log . info ( "added class {} to publishers" , annotatedPublisher ) ;
} catch ( Throwable e ) {
log . error ( "publisher class {} cannot be instantiated" , annotatedPublisher . getCanonicalName ( ) , e ) ;
}
}
this . publishers = foundPublishers ;
if ( foundPublishers . isEmpty ( ) )
log . warn ( "no publishers found in classloader" ) ;
}
return this . publishers ;
}
/ *
@Override
public AuthorizationProvider authorizationProvider ( ) {
return containerContext . authorizationProvider ( ) ;
}
* /
/ *
* @Override public AuthorizationProvider authorizationProvider ( ) { return
* containerContext . authorizationProvider ( ) ; }
* /
}