2017-04-03 17:15:36 +02:00
package org.gcube.smartgears.handler.resourceregistry ;
import static org.gcube.common.events.Observes.Kind.resilient ;
import static org.gcube.smartgears.handler.resourceregistry.Constants.ESERVICE_PROPERTY ;
import static org.gcube.smartgears.handler.resourceregistry.Constants.RESOURCE_MANAGEMENT ;
import static org.gcube.smartgears.handlers.ProfileEvents.addToContext ;
import static org.gcube.smartgears.handlers.ProfileEvents.removeFromContext ;
import static org.gcube.smartgears.lifecycle.application.ApplicationLifecycle.activation ;
import static org.gcube.smartgears.lifecycle.application.ApplicationLifecycle.failure ;
import static org.gcube.smartgears.lifecycle.application.ApplicationLifecycle.stop ;
import static org.gcube.smartgears.utils.Utils.rethrowUnchecked ;
import java.net.URI ;
import java.util.Arrays ;
import java.util.List ;
import java.util.Set ;
import java.util.UUID ;
import java.util.concurrent.ScheduledFuture ;
import java.util.concurrent.TimeUnit ;
import javax.servlet.ServletRegistration ;
import javax.xml.bind.annotation.XmlRootElement ;
import org.gcube.common.authorization.client.proxy.AuthorizationProxy ;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider ;
import org.gcube.common.events.Observes ;
import org.gcube.common.scope.api.ScopeProvider ;
import org.gcube.informationsystem.impl.embedded.HeaderImpl ;
import org.gcube.informationsystem.impl.embedded.PropagationConstraintImpl ;
import org.gcube.informationsystem.impl.embedded.ValueSchemaImpl ;
import org.gcube.informationsystem.impl.entity.facet.AccessPointFacetImpl ;
import org.gcube.informationsystem.impl.entity.facet.ServiceStateFacetImpl ;
import org.gcube.informationsystem.impl.entity.facet.SoftwareFacetImpl ;
import org.gcube.informationsystem.impl.entity.resource.EServiceImpl ;
import org.gcube.informationsystem.impl.relation.ConsistsOfImpl ;
import org.gcube.informationsystem.impl.relation.IsIdentifiedByImpl ;
import org.gcube.informationsystem.impl.relation.isrelatedto.HostsImpl ;
import org.gcube.informationsystem.model.embedded.Header ;
import org.gcube.informationsystem.model.embedded.PropagationConstraint ;
import org.gcube.informationsystem.model.embedded.PropagationConstraint.AddConstraint ;
import org.gcube.informationsystem.model.embedded.PropagationConstraint.RemoveConstraint ;
import org.gcube.informationsystem.model.embedded.ValueSchema ;
import org.gcube.informationsystem.model.entity.Resource ;
import org.gcube.informationsystem.model.entity.facet.AccessPointFacet ;
import org.gcube.informationsystem.model.entity.facet.ServiceStateFacet ;
import org.gcube.informationsystem.model.entity.facet.SoftwareFacet ;
import org.gcube.informationsystem.model.entity.resource.EService ;
import org.gcube.informationsystem.model.entity.resource.HostingNode ;
import org.gcube.informationsystem.model.relation.ConsistsOf ;
import org.gcube.informationsystem.model.relation.IsIdentifiedBy ;
import org.gcube.informationsystem.model.relation.IsRelatedTo ;
import org.gcube.informationsystem.model.relation.isrelatedto.Hosts ;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException ;
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAlreadyPresentException ;
2017-04-04 16:18:14 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceAvailableInAnotherContextException ;
2017-04-03 17:15:36 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.entity.resource.ResourceNotFoundException ;
2017-04-26 16:48:26 +02:00
import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERAvailableInAnotherContextException ;
import org.gcube.informationsystem.resourceregistry.api.exceptions.er.ERNotFoundException ;
2017-04-04 14:01:32 +02:00
import org.gcube.informationsystem.resourceregistry.client.Direction ;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient ;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClientFactory ;
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisher ;
import org.gcube.informationsystem.resourceregistry.publisher.ResourceRegistryPublisherFactory ;
2017-04-03 17:15:36 +02:00
import org.gcube.smartgears.configuration.application.ApplicationConfiguration ;
import org.gcube.smartgears.configuration.container.ContainerConfiguration ;
import org.gcube.smartgears.context.Property ;
import org.gcube.smartgears.context.application.ApplicationContext ;
import org.gcube.smartgears.handlers.application.ApplicationLifecycleEvent ;
import org.gcube.smartgears.handlers.application.ApplicationLifecycleHandler ;
import org.gcube.smartgears.lifecycle.application.ApplicationLifecycle ;
import org.gcube.smartgears.lifecycle.application.ApplicationState ;
import org.gcube.smartgears.lifecycle.container.ContainerLifecycle ;
import org.gcube.smartgears.provider.ProviderFactory ;
import org.gcube.smartgears.utils.Utils ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
/ * *
* Manages the { @link EService } { @link Resource } of the application .
* < p >
* The manager :
* < ul >
* < li >
* creates the { @link EService } { @link Resource } and the facets it
* { @link ConsistsOf } when the application starts for the first time ; < / li >
* < li >
* update the { @link ServiceStateFacet } when the application becomes active , and
* at any lifecycle change thereafter ; < / li >
* < / ul >
* < / p >
*
* @author Luca Frosini
* /
@XmlRootElement ( name = RESOURCE_MANAGEMENT )
public class EServiceManager extends ApplicationLifecycleHandler {
private static final Logger logger = LoggerFactory
. getLogger ( EServiceManager . class ) ;
private ApplicationContext applicationContext ;
private AuthorizationProxy authorizationProxy ;
private ScheduledFuture < ? > periodicUpdates ;
private static List < String > servletExcludes = Arrays . asList ( " default " , " jsp " ) ;
public EServiceManager ( ) {
super ( ) ;
this . authorizationProxy = ProviderFactory . provider ( )
. authorizationProxy ( ) ;
}
private void setContextFromToken ( String token ) {
if ( token = = null | | token . compareTo ( " " ) = = 0 ) {
SecurityTokenProvider . instance . reset ( ) ;
ScopeProvider . instance . reset ( ) ;
} else {
SecurityTokenProvider . instance . set ( token ) ;
2017-04-04 16:18:14 +02:00
String scope = getContextName ( token ) ;
2017-04-03 17:15:36 +02:00
ScopeProvider . instance . set ( scope ) ;
}
}
@Override
public void onStart ( ApplicationLifecycleEvent . Start e ) {
this . applicationContext = e . context ( ) ;
EService eService = instantiateEService ( ) ;
eService = publishEservice ( eService ) ;
registerObservers ( ) ;
schedulePeriodicUpdates ( ) ;
}
private void share ( EService eService ) {
logger . trace ( " sharing EService for {} " , applicationContext . name ( ) ) ;
applicationContext . properties ( ) . add (
new Property ( ESERVICE_PROPERTY , eService ) ) ;
}
// helpers
private void registerObservers ( ) {
applicationContext . events ( ) . subscribe ( new Object ( ) {
@Observes ( { activation , stop , failure } )
void onChanged ( ApplicationLifecycle lc ) {
2017-04-26 16:48:26 +02:00
String state = getState ( lc ) ;
2017-04-03 17:15:36 +02:00
logger . debug ( " Moving app {} to {} " , applicationContext . name ( ) ,
state ) ;
2017-04-26 16:48:26 +02:00
try {
createOrUpdateServiceStateFacet ( getEService ( ) , state ) ;
} catch ( ResourceRegistryException e ) {
rethrowUnchecked ( e ) ;
}
2017-04-03 17:15:36 +02:00
}
@Observes ( value = addToContext )
void addTo ( String token ) {
2017-04-04 16:18:14 +02:00
//EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class);
//addToContext(eService, token);
addHostingNodeToContext ( token ) ;
2017-04-03 17:15:36 +02:00
}
@Observes ( value = removeFromContext )
void removeFrom ( String token ) {
2017-04-04 16:18:14 +02:00
// EService eService = applicationContext.properties().lookup(Constants.ESERVICE_PROPERTY).value(EService.class);
// removeFromContext(eService, token);
removeHostingNodeFromContext ( token ) ;
2017-04-03 17:15:36 +02:00
}
2017-04-26 16:48:26 +02:00
2017-04-03 17:15:36 +02:00
} ) ;
}
2017-04-26 16:48:26 +02:00
private String getState ( ApplicationLifecycle lc ) {
return lc . state ( ) . remoteForm ( ) . toLowerCase ( ) ;
}
2017-04-03 17:15:36 +02:00
private void schedulePeriodicUpdates ( ) {
// register to cancel updates
applicationContext . events ( ) . subscribe (
new Object ( ) {
// we register it in response to lifecycle events so that we can
// stop and resume along with application
@Observes ( value = { activation } , kind = resilient )
synchronized void restartPeriodicUpdates (
final ApplicationLifecycle lc ) {
// already running
if ( periodicUpdates ! = null ) {
return ;
}
if ( lc . state ( ) = = ApplicationState . active ) {
logger . info (
" scheduling periodic updates of application {} EService " ,
applicationContext . name ( ) ) ;
} else {
logger . info (
" resuming periodic updates of application {} EService " ,
applicationContext . name ( ) ) ;
}
final Runnable updateTask = new Runnable ( ) {
public void run ( ) {
try {
2017-04-26 16:48:26 +02:00
String state = getState ( lc ) ;
createOrUpdateServiceStateFacet ( getEService ( ) , state ) ;
2017-04-03 17:15:36 +02:00
} catch ( Exception e ) {
logger . error (
" cannot complete periodic update of EService " ,
e ) ;
}
}
} ;
periodicUpdates = Utils . scheduledServicePool
. scheduleAtFixedRate (
updateTask ,
Constants . application_republish_frequency_in_minutes ,
Constants . application_republish_frequency_in_minutes ,
TimeUnit . MINUTES ) ;
}
@Observes ( value = { stop , failure } , kind = resilient )
synchronized void cancelPeriodicUpdates ( ContainerLifecycle ignore ) {
if ( periodicUpdates ! = null ) {
logger . trace (
" stopping periodic updates of application {} EService " ,
applicationContext . name ( ) ) ;
try {
periodicUpdates . cancel ( true ) ;
periodicUpdates = null ;
} catch ( Exception e ) {
logger . warn (
" could not stop periodic updates of application {} EService " ,
applicationContext . name ( ) , e ) ;
}
}
}
} ) ;
}
@SuppressWarnings ( " unchecked " )
private void createHostsRelation ( EService eService ,
ResourceRegistryPublisher resourceRegistryPublisher ) {
2017-04-04 16:18:14 +02:00
2017-04-03 17:15:36 +02:00
HostingNode hostingNode = applicationContext . container ( ) . properties ( ) . lookup ( Constants . HOSTING_NODE_PROPERTY ) . value ( HostingNode . class ) ;
2017-04-28 16:54:29 +02:00
addHostingNodeToCurrentContext ( ) ;
2017-04-03 17:15:36 +02:00
if ( hostingNode ! = null ) {
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory . create ( ) ;
Hosts < HostingNode , EService > hosts = null ;
try {
List < Resource > resources = resourceRegistryClient . getInstancesFromEntity ( Hosts . NAME , false , hostingNode . getHeader ( ) . getUUID ( ) , Direction . out ) ;
for ( Resource resource : resources ) {
if ( resource instanceof HostingNode & & resource . getHeader ( ) . getUUID ( ) . compareTo ( hostingNode . getHeader ( ) . getUUID ( ) ) = = 0 ) {
List < IsRelatedTo < ? extends Resource , ? extends Resource > > isRelatedToList = resource . getIsRelatedTo ( ) ;
for ( IsRelatedTo < ? extends Resource , ? extends Resource > isRelatedTo : isRelatedToList ) {
if ( isRelatedTo instanceof Hosts ) {
if ( isRelatedTo . getTarget ( ) . getHeader ( ) . getUUID ( )
. compareTo ( eService . getHeader ( ) . getUUID ( ) ) = = 0 ) {
hosts = ( Hosts < HostingNode , EService > ) isRelatedTo ;
break ;
}
}
}
}
}
2017-04-04 16:18:14 +02:00
} catch ( Exception e ) {
logger . warn ( " Error while trying to retrieve Hosts relation " , e ) ;
2017-04-03 17:15:36 +02:00
}
if ( hosts = = null ) {
PropagationConstraint propagationConstraint = new PropagationConstraintImpl ( ) ;
propagationConstraint
. setRemoveConstraint ( RemoveConstraint . cascade ) ;
propagationConstraint
. setAddConstraint ( AddConstraint . propagate ) ;
hosts = new HostsImpl < > ( hostingNode , eService ,
propagationConstraint ) ;
try {
hosts = resourceRegistryPublisher . createIsRelatedTo (
Hosts . class , hosts ) ;
} catch ( ResourceNotFoundException e ) {
logger . error ( " THIS IS REALLY STRANGE. YOU SHOULD NE BE HERE. Error while creating {}. " , hosts , e ) ;
} catch ( ResourceRegistryException e ) {
logger . error ( " Error while creating {} " , hosts , e ) ;
}
}
}
}
2017-04-26 16:48:26 +02:00
private EService getEService ( ) throws ResourceRegistryException {
EService eService = null ;
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory . create ( ) ;
UUID eServiceUUID = UUID . fromString ( this . applicationContext . id ( ) ) ;
try {
resourceRegistryClient . exists ( EService . class , eServiceUUID ) ;
eService = resourceRegistryClient . getInstance ( EService . class , eServiceUUID ) ;
} catch ( ERNotFoundException e ) {
eService = instantiateEService ( ) ;
eService = publishEservice ( eService ) ;
} catch ( ERAvailableInAnotherContextException e ) {
addHostingNodeToCurrentContext ( ) ;
eService = resourceRegistryClient . getInstance ( EService . class , eServiceUUID ) ;
} catch ( ResourceRegistryException e ) {
throw e ;
}
return eService ;
}
2017-04-03 17:15:36 +02:00
private EService createEServiceAndHosts (
ResourceRegistryPublisher resourceRegistryPublisher ,
EService eService ) throws ResourceRegistryException {
2017-04-04 16:18:14 +02:00
2017-04-03 17:15:36 +02:00
try {
eService = resourceRegistryPublisher . createResource ( EService . class ,
eService ) ;
} catch ( ResourceAlreadyPresentException e ) {
2017-04-04 16:18:14 +02:00
ResourceRegistryClient registryClient = ResourceRegistryClientFactory . create ( ) ;
eService = registryClient . getInstance ( EService . class , eService . getHeader ( ) . getUUID ( ) ) ;
2017-04-06 15:05:03 +02:00
String state = applicationContext . lifecycle ( ) . state ( ) . remoteForm ( ) . toLowerCase ( ) ;
logger . debug ( " Moving app {} to {} " , applicationContext . name ( ) , state ) ;
createOrUpdateServiceStateFacet ( eService , state ) ;
2017-04-04 16:18:14 +02:00
} catch ( ResourceAvailableInAnotherContextException e ) {
2017-05-02 17:55:29 +02:00
// Adding the HostingNode I also add the EService thanks to propagationConstraint
String token = SecurityTokenProvider . instance . get ( ) ;
// If hosts was not created we need to add eService and HostingNode, otherwise
// addHostingnode is sufficient. Because we cannot be sure of it we invoke both
addToContext ( eService , token ) ;
2017-04-04 16:18:14 +02:00
addHostingNodeToCurrentContext ( ) ;
ResourceRegistryClient registryClient = ResourceRegistryClientFactory . create ( ) ;
eService = registryClient . getInstance ( EService . class , eService . getHeader ( ) . getUUID ( ) ) ;
2017-04-03 17:15:36 +02:00
}
2017-05-02 17:55:29 +02:00
try {
createHostsRelation ( eService , resourceRegistryPublisher ) ;
} catch ( Exception ex ) {
String error = String . format (
" Unable to Create %s relation from % to % (%s : %s) " ,
Hosts . NAME , HostingNode . NAME , EService . NAME ,
applicationContext . name ( ) , eService . getHeader ( ) . getUUID ( ) ) ;
logger . error ( error , ex ) ;
throw new ResourceRegistryException ( error , ex ) ;
}
2017-04-03 17:15:36 +02:00
return eService ;
}
2017-04-04 16:18:14 +02:00
private void shareHostingNode ( HostingNode hostingNode ) {
logger . trace ( " sharing {} {} " , HostingNode . NAME , Resource . NAME ) ;
applicationContext . container ( ) . properties ( ) . add (
new Property ( Constants . HOSTING_NODE_PROPERTY , hostingNode ) ) ;
}
2017-04-03 17:15:36 +02:00
private EService publishEservice ( EService eService ) {
ClassLoader contextCL = Thread . currentThread ( ) . getContextClassLoader ( ) ;
String previousToken = SecurityTokenProvider . instance . get ( ) ;
try {
Thread . currentThread ( ) . setContextClassLoader (
EServiceManager . class . getClassLoader ( ) ) ;
boolean create = true ;
2017-04-04 16:18:14 +02:00
Set < String > startTokens = applicationContext . configuration ( ) . startTokens ( ) ;
2017-04-03 17:15:36 +02:00
for ( String token : startTokens ) {
setContextFromToken ( token ) ;
try {
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory
. create ( ) ;
if ( create ) {
eService = createEServiceAndHosts (
resourceRegistryPublisher , eService ) ;
2017-04-04 16:18:14 +02:00
share ( eService ) ;
2017-04-03 17:15:36 +02:00
create = false ;
} else {
2017-04-04 16:18:14 +02:00
addHostingNodeToContext ( token ) ;
2017-04-03 17:15:36 +02:00
}
} catch ( ResourceRegistryException e ) {
logger . error ( " Unable to add {} to current context ({}) " ,
2017-04-04 16:18:14 +02:00
eService , getContextName ( token ) , e ) ;
2017-04-03 17:15:36 +02:00
}
}
} catch ( Exception e ) {
rethrowUnchecked ( e ) ;
} finally {
setContextFromToken ( previousToken ) ;
Thread . currentThread ( ) . setContextClassLoader ( contextCL ) ;
}
return eService ;
}
2017-04-04 16:18:14 +02:00
private String getCurrentContextName ( ) {
String token = SecurityTokenProvider . instance . get ( ) ;
return getContextName ( token ) ;
}
private String getContextName ( String token ) {
2017-04-03 17:15:36 +02:00
try {
return this . authorizationProxy . get ( token ) . getContext ( ) ;
} catch ( Exception e ) {
logger . error ( " Error retrieving token {}, it should never happen " ,
token ) ;
return null ;
}
}
2017-04-04 16:18:14 +02:00
private boolean addHostingNodeToCurrentContext ( ) {
String token = SecurityTokenProvider . instance . get ( ) ;
return addHostingNodeToContext ( token ) ;
}
private boolean addHostingNodeToContext ( String token ) {
HostingNode hostingNode = applicationContext . container ( ) . properties ( ) . lookup ( Constants . HOSTING_NODE_PROPERTY ) . value ( HostingNode . class ) ;
ClassLoader contextCL = Thread . currentThread ( ) . getContextClassLoader ( ) ;
String previousToken = SecurityTokenProvider . instance . get ( ) ;
try {
Thread . currentThread ( ) . setContextClassLoader (
EServiceManager . class . getClassLoader ( ) ) ;
setContextFromToken ( token ) ;
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory . create ( ) ;
resourceRegistryPublisher . addResourceToContext ( hostingNode ) ;
logger . info ( " {} successfully added to current context ({}) " ,
hostingNode , getContextName ( token ) ) ;
shareHostingNode ( hostingNode ) ;
return true ;
} catch ( Exception e ) {
logger . error ( " Unable to add {} to current context ({}) " , hostingNode ,
getCurrentContextName ( ) , e ) ;
rethrowUnchecked ( e ) ;
return false ;
} finally {
setContextFromToken ( previousToken ) ;
Thread . currentThread ( ) . setContextClassLoader ( contextCL ) ;
}
}
/ *
private boolean removeHostingNodeFromContext ( ) {
String token = SecurityTokenProvider . instance . get ( ) ;
return removeHostingNodeFromContext ( token ) ;
}
* /
private boolean removeHostingNodeFromContext ( String token ) {
HostingNode hostingNode = applicationContext . container ( ) . properties ( ) . lookup ( Constants . HOSTING_NODE_PROPERTY ) . value ( HostingNode . class ) ;
ClassLoader contextCL = Thread . currentThread ( ) . getContextClassLoader ( ) ;
String previousToken = SecurityTokenProvider . instance . get ( ) ;
try {
Thread . currentThread ( ) . setContextClassLoader (
EServiceManager . class . getClassLoader ( ) ) ;
setContextFromToken ( token ) ;
ResourceRegistryPublisher resourceRegistryPublisher =
ResourceRegistryPublisherFactory . create ( ) ;
resourceRegistryPublisher
. removeResourceFromContext ( hostingNode ) ;
2017-04-03 17:15:36 +02:00
2017-04-04 16:18:14 +02:00
logger . info ( " {} successfully removed from current context ({}) " ,
hostingNode , getContextName ( token ) ) ;
shareHostingNode ( hostingNode ) ;
return true ;
} catch ( Exception e ) {
logger . error ( " Unable to remove {} from current context ({}) " ,
hostingNode , getContextName ( token ) , e ) ;
rethrowUnchecked ( e ) ;
return false ;
} finally {
setContextFromToken ( previousToken ) ;
Thread . currentThread ( ) . setContextClassLoader ( contextCL ) ;
}
}
/ *
2017-04-03 17:15:36 +02:00
private void removeFromContext ( EService eService , String token ) {
ClassLoader contextCL = Thread . currentThread ( ) . getContextClassLoader ( ) ;
String previousToken = SecurityTokenProvider . instance . get ( ) ;
try {
Thread . currentThread ( ) . setContextClassLoader (
EServiceManager . class . getClassLoader ( ) ) ;
setContextFromToken ( token ) ;
boolean removed = false ;
ResourceRegistryPublisher resourceRegistryPublisher =
ResourceRegistryPublisherFactory . create ( ) ;
removed = resourceRegistryPublisher
. removeResourceFromContext ( eService ) ;
if ( removed ) {
logger . info (
" {} successfully removed from current context ({}) " ,
2017-04-04 16:18:14 +02:00
eService , getContextName ( token ) ) ;
2017-04-03 17:15:36 +02:00
share ( eService ) ;
} else {
logger . error ( " Unable to remove {} from current context ({}) " ,
2017-04-04 16:18:14 +02:00
eService , getContextName ( token ) ) ;
2017-04-03 17:15:36 +02:00
}
share ( eService ) ;
} catch ( Exception e ) {
logger . error ( " Unable to remove {} from current context ({}) " ,
2017-04-04 16:18:14 +02:00
eService , getContextName ( token ) , e ) ;
2017-04-03 17:15:36 +02:00
rethrowUnchecked ( e ) ;
} finally {
setContextFromToken ( previousToken ) ;
Thread . currentThread ( ) . setContextClassLoader ( contextCL ) ;
}
}
2017-05-02 17:55:29 +02:00
* /
2017-04-03 17:15:36 +02:00
private void addToContext ( EService eService , String token ) {
ClassLoader contextCL = Thread . currentThread ( ) . getContextClassLoader ( ) ;
String previousToken = SecurityTokenProvider . instance . get ( ) ;
try {
Thread . currentThread ( ) . setContextClassLoader (
EServiceManager . class . getClassLoader ( ) ) ;
setContextFromToken ( token ) ;
ResourceRegistryPublisher resourceRegistryPublisher =
ResourceRegistryPublisherFactory . create ( ) ;
boolean added = resourceRegistryPublisher
. addResourceToContext ( eService ) ;
if ( added ) {
logger . info ( " {} successfully added to current context ({}) " ,
2017-04-04 16:18:14 +02:00
eService , getContextName ( token ) ) ;
2017-04-03 17:15:36 +02:00
share ( eService ) ;
} else {
logger . error ( " Unable to add {} to current context ({}) " ,
2017-04-04 16:18:14 +02:00
eService , getContextName ( token ) ) ;
2017-04-03 17:15:36 +02:00
}
share ( eService ) ;
} catch ( Exception e ) {
logger . error ( " Unable to add {} to current context ({}) " , eService ,
2017-04-04 16:18:14 +02:00
getContextName ( token ) , e ) ;
2017-04-03 17:15:36 +02:00
rethrowUnchecked ( e ) ;
} finally {
setContextFromToken ( previousToken ) ;
Thread . currentThread ( ) . setContextClassLoader ( contextCL ) ;
}
}
2017-04-04 16:18:14 +02:00
2017-04-26 16:48:26 +02:00
@SuppressWarnings ( " unchecked " )
private void createOrUpdateServiceStateFacet ( EService eService , String state ) throws ResourceRegistryException {
2017-05-02 17:28:47 +02:00
String previousToken = SecurityTokenProvider . instance . get ( ) ;
if ( previousToken = = null ) {
setContextFromToken ( ( String ) applicationContext . configuration ( ) . startTokens ( ) . toArray ( ) [ 0 ] ) ;
}
2017-04-03 17:15:36 +02:00
ClassLoader contextCL = Thread . currentThread ( ) . getContextClassLoader ( ) ;
2017-04-26 16:48:26 +02:00
Thread . currentThread ( ) . setContextClassLoader ( EServiceManager . class . getClassLoader ( ) ) ;
ResourceRegistryClient resourceRegistryClient = ResourceRegistryClientFactory
. create ( ) ;
ResourceRegistryPublisher resourceRegistryPublisher = ResourceRegistryPublisherFactory
. create ( ) ;
UUID eServiceUUID = eService . getHeader ( ) . getUUID ( ) ;
2017-04-03 17:15:36 +02:00
try {
ServiceStateFacet serviceStateFacet = null ;
2017-04-26 16:48:26 +02:00
List < ServiceStateFacet > serviceStateFacets = eService . getFacets ( ServiceStateFacet . class ) ;
if ( serviceStateFacets ! = null & & serviceStateFacets . size ( ) > = 1 ) {
serviceStateFacet = serviceStateFacets . get ( 0 ) ;
2017-04-03 17:15:36 +02:00
serviceStateFacet . setValue ( state ) ;
2017-04-26 16:48:26 +02:00
serviceStateFacet = resourceRegistryPublisher . updateFacet ( ServiceStateFacet . class , serviceStateFacet ) ;
for ( int i = 1 ; i < serviceStateFacets . size ( ) ; i + + ) {
try {
logger . warn ( " You should not be here. There are more than one {}. Anyway deleting it : {} " , ServiceStateFacet . class . getSimpleName ( ) , serviceStateFacets . get ( i ) ) ;
resourceRegistryPublisher . deleteFacet ( serviceStateFacets . get ( i ) ) ;
} catch ( Exception e ) {
logger . warn ( " Unable to delete {} which should not exists : {} " , ServiceStateFacet . class . getSimpleName ( ) , serviceStateFacets . get ( i ) ) ;
}
2017-04-03 17:15:36 +02:00
}
2017-04-26 16:48:26 +02:00
} else {
serviceStateFacet = new ServiceStateFacetImpl ( ) ;
serviceStateFacet . setValue ( state ) ;
serviceStateFacet = resourceRegistryPublisher . createFacet ( ServiceStateFacet . class , serviceStateFacet ) ;
ConsistsOf < EService , ServiceStateFacet > consistsOf = new ConsistsOfImpl < EService , ServiceStateFacet > (
eService , serviceStateFacet , null ) ;
consistsOf = resourceRegistryPublisher . createConsistsOf ( ConsistsOf . class , consistsOf ) ;
2017-04-03 17:15:36 +02:00
}
2017-04-26 16:48:26 +02:00
eService = resourceRegistryClient . getInstance ( EService . class , eServiceUUID ) ;
2017-04-03 17:15:36 +02:00
share ( eService ) ;
} catch ( Exception e ) {
rethrowUnchecked ( e ) ;
} finally {
Thread . currentThread ( ) . setContextClassLoader ( contextCL ) ;
}
}
2017-04-04 16:55:17 +02:00
private static String getBaseAddress ( ApplicationContext context ) {
ApplicationConfiguration configuration = context . configuration ( ) ;
ContainerConfiguration container = context . container ( ) . configuration ( ) ;
String baseAddress ;
if ( configuration . proxied ( ) ) {
String protocol = container . proxyAddress ( ) . secure ( ) ? " https:// " : " http:// " ;
int port = container . proxyAddress ( ) . port ( ) ;
baseAddress = String . format ( " %s%s:%d%s " , protocol , container . proxyAddress ( ) . hostname ( ) , port , context . application ( ) . getContextPath ( ) ) ;
} else {
String protocol = configuration . secure ( ) ? " https:// " : " http:// " ;
int port = configuration . secure ( ) ? container . securePort ( ) : container . port ( ) ;
baseAddress = String . format ( " %s%s:%d%s " , protocol , container . hostname ( ) , port , context . application ( ) . getContextPath ( ) ) ;
}
return baseAddress ;
}
2017-04-03 17:15:36 +02:00
private EService instantiateEService ( ) {
logger . info ( " Creating EService for {} " , applicationContext . name ( ) ) ;
ApplicationConfiguration applicationConfiguration = applicationContext
. configuration ( ) ;
UUID uuid = UUID . fromString ( this . applicationContext . id ( ) ) ;
EService eService = new EServiceImpl ( ) ;
Header header = new HeaderImpl ( uuid ) ;
eService . setHeader ( header ) ;
SoftwareFacet softwareFacet = new SoftwareFacetImpl ( ) ;
softwareFacet . setDescription ( applicationConfiguration . description ( ) ) ;
softwareFacet . setGroup ( applicationConfiguration . serviceClass ( ) ) ;
softwareFacet . setName ( applicationConfiguration . name ( ) ) ;
softwareFacet . setVersion ( applicationConfiguration . version ( ) ) ;
IsIdentifiedBy < EService , SoftwareFacet > isIdentifiedBy = new IsIdentifiedByImpl < EService , SoftwareFacet > (
eService , softwareFacet , null ) ;
eService . addFacet ( isIdentifiedBy ) ;
2017-04-04 16:55:17 +02:00
String baseAddress = EServiceManager . getBaseAddress ( applicationContext ) ;
2017-04-03 17:15:36 +02:00
for ( ServletRegistration servlet : applicationContext . application ( )
. getServletRegistrations ( ) . values ( ) ) {
if ( ! servletExcludes . contains ( servlet . getName ( ) ) ) {
for ( String mapping : servlet . getMappings ( ) ) {
String address = baseAddress + ( mapping . endsWith ( " * " ) ? mapping . substring ( 0 , mapping . length ( ) - 2 ) : mapping ) ;
AccessPointFacet accessPointFacet = new AccessPointFacetImpl ( ) ;
accessPointFacet . setEntryName ( servlet . getName ( ) ) ;
accessPointFacet . setEndpoint ( URI . create ( address ) ) ;
ValueSchema valueSchema = new ValueSchemaImpl ( ) ;
valueSchema . setValue ( " gcube-token " ) ;
accessPointFacet . setAuthorization ( valueSchema ) ;
eService . addFacet ( accessPointFacet ) ;
}
}
}
ServiceStateFacet serviceStateFacet = new ServiceStateFacetImpl ( ) ;
2017-04-26 16:48:26 +02:00
String state = getState ( applicationContext . lifecycle ( ) ) ;
2017-04-03 17:15:36 +02:00
serviceStateFacet . setValue ( state . toLowerCase ( ) ) ;
eService . addFacet ( serviceStateFacet ) ;
return eService ;
}
@Override
public String toString ( ) {
return RESOURCE_MANAGEMENT ;
}
}