2019-04-05 16:39:46 +02:00
package org.gcube.portal.social.networking.caches ;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor ;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor ;
import java.io.InputStream ;
import java.util.List ;
import java.util.Properties ;
import net.sf.ehcache.Ehcache ;
import net.sf.ehcache.Element ;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite ;
import org.gcube.common.portal.GCubePortalConstants ;
import org.gcube.common.resources.gcore.ServiceEndpoint ;
import org.gcube.common.scope.api.ScopeProvider ;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder ;
import org.gcube.resources.discovery.client.api.DiscoveryClient ;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery ;
import org.gcube.smartgears.ContextProvider ;
import org.gcube.smartgears.context.application.ApplicationContext ;
import org.gcube.vomanagement.usermanagement.GroupManager ;
import org.gcube.vomanagement.usermanagement.model.GCubeGroup ;
import org.gcube.vomanagement.usermanagement.model.VirtualGroup ;
import org.slf4j.LoggerFactory ;
/ * *
* When a notification needs to be sent , this class offers utility to discover ( starting from the scope )
* the site information needed to build up the SocialNetworkingSite object ( which , for instance , contains the
* portal email ) .
* @author Costantino Perciante at ISTI - CNR ( costantino . perciante @isti.cnr.it )
* /
public class SocialNetworkingSiteFinder {
// Logger
private static final org . slf4j . Logger logger = LoggerFactory . getLogger ( SocialNetworkingSiteFinder . class ) ;
private static final String EMAIL_SENDER_SITE_CUSTOM_FIELD = " Emailsender " ;
private static final String CATEGORY = " Portal " ;
// these properties could be overwritten by the ones read from config.properties
private static String PROD_FALLBACK_GATEWAY = " D4Science.org Gateway " ;
2019-04-11 14:36:53 +02:00
private static String DEV_FALLBACK_GATEWAY = " gCube Snapshot Gateway " ;
private static String PREPROD_FALLBACK_GATEWAY = " D4Science Preproduction Gateway " ;
2019-04-05 16:39:46 +02:00
/ * *
* Singleton object
* /
private static SocialNetworkingSiteFinder singleton = new SocialNetworkingSiteFinder ( ) ;
/ * *
* Build the singleton instance
* /
private SocialNetworkingSiteFinder ( ) {
// read fallback properties
try {
logger . info ( " Trying to read config.properties " ) ;
ClassLoader classLoader = Thread . currentThread ( ) . getContextClassLoader ( ) ;
InputStream input = classLoader . getResourceAsStream ( " config.properties " ) ;
Properties properties = new Properties ( ) ;
properties . load ( input ) ;
PROD_FALLBACK_GATEWAY = properties . getProperty ( " PROD_FALLBACK_GATEWAY " ) ;
DEV_FALLBACK_GATEWAY = properties . getProperty ( " DEV_FALLBACK_GATEWAY " ) ;
PREPROD_FALLBACK_GATEWAY = properties . getProperty ( " PREPROD_FALLBACK_GATEWAY " ) ;
} catch ( Exception e ) {
logger . warn ( " Failed to read config.properties... " , e ) ;
}
}
/ * *
* Retrieve the singleton instance
* /
public static SocialNetworkingSiteFinder getInstance ( ) {
return singleton ;
}
/ * *
* Retrieve the SocialNetworkingSite given the scope
* @param scope
* @return
* /
public static SocialNetworkingSite getSocialNetworkingSiteFromScope ( String scope ) {
Ehcache socialSitesCache = CachesManager . getCache ( CachesManager . SOCIAL_NETWORKING_SITES_CACHE ) ;
if ( scope = = null | | scope . isEmpty ( ) )
throw new IllegalArgumentException ( " Scope cannot be null/empty " ) ;
2023-09-29 17:44:32 +02:00
if ( socialSitesCache ! = null & & socialSitesCache . get ( scope ) ! = null )
2019-04-05 16:39:46 +02:00
return ( SocialNetworkingSite ) socialSitesCache . get ( scope ) . getObjectValue ( ) ;
else {
SocialNetworkingSite site = discoverSite ( scope ) ;
2023-09-29 17:52:51 +02:00
if ( socialSitesCache ! = null & & site ! = null )
2019-04-05 16:39:46 +02:00
socialSitesCache . put ( new Element ( scope , site ) ) ;
return site ;
}
}
/ * *
* Discover the site for this scope
* @param scope
* @return
* /
private static SocialNetworkingSite discoverSite ( String scope ) {
try {
logger . info ( " Requested site for scope " + scope ) ;
GroupManager groupManager = GroupManagerWSBuilder . getInstance ( ) . getGroupManager ( ) ;
long groupId = groupManager . getGroupIdFromInfrastructureScope ( scope ) ;
GCubeGroup matchingGateway = null ;
if ( groupManager . isVRE ( groupId ) ) {
// get the Virtual groups for the groupid related to the scope
List < VirtualGroup > virtualGroupsOfGroup = groupManager . getVirtualGroups ( groupId ) ;
if ( virtualGroupsOfGroup = = null | | virtualGroupsOfGroup . isEmpty ( ) )
throw new Exception ( " It seems that the VRE is not linked to any VirtualGroups " ) ;
// get the gateways
List < GCubeGroup > gateways = groupManager . getGateways ( ) ;
if ( gateways = = null | | gateways . isEmpty ( ) )
throw new Exception ( " It seems there is no gateway here! " ) ;
logger . info ( " Retrieved Gateways are " + gateways ) ;
// now, retrieve the virtual groups for each gateway and stop when a VG matches with one of the group
// then, it is the gateway of interest
ext_loop : for ( GCubeGroup gateway : gateways ) {
List < VirtualGroup > gatewayVirtualGroups = groupManager . getVirtualGroups ( gateway . getGroupId ( ) ) ;
if ( gatewayVirtualGroups ! = null & & ! gatewayVirtualGroups . isEmpty ( ) ) {
for ( VirtualGroup gatewayVirtualGroup : gatewayVirtualGroups ) {
if ( virtualGroupsOfGroup . contains ( gatewayVirtualGroup ) ) {
logger . info ( " Matching gateway for scope " + scope + " is " + gateway ) ;
matchingGateway = gateway ;
break ext_loop ;
}
}
}
}
} else {
List < GCubeGroup > gateways = groupManager . getGateways ( ) ;
// vo and root vo cases are treated separately: in production environment services.d4science.org is used, instead
// in dev next.d4science.org is used TODO better way...
ApplicationContext ctx = ContextProvider . get ( ) ; // get this info from SmartGears
String rootContext = " / " + ctx . container ( ) . configuration ( ) . infrastructure ( ) ;
String matchingGatewayName = null ;
if ( isDevOrPreprod ( rootContext ) ) {
matchingGatewayName = DEV_FALLBACK_GATEWAY ;
} else {
matchingGatewayName = PROD_FALLBACK_GATEWAY ;
}
// find the matching one among the gateways
for ( GCubeGroup gateway : gateways ) {
if ( gateway . getGroupName ( ) . equals ( matchingGatewayName ) ) {
matchingGateway = gateway ;
break ;
}
}
if ( matchingGateway = = null & & isDevOrPreprod ( rootContext ) ) {
logger . warn ( " Checking if it is the preprod environment " ) ;
matchingGatewayName = PREPROD_FALLBACK_GATEWAY ;
// find the matching one among the gateways
for ( GCubeGroup gateway : gateways ) {
if ( gateway . getGroupName ( ) . equals ( matchingGatewayName ) ) {
matchingGateway = gateway ;
break ;
}
}
}
}
if ( matchingGateway = = null ) {
logger . warn ( " There is no gateway for such scope. Returning null " ) ;
return null ;
} else {
String siteName = matchingGateway . getGroupName ( ) ;
String emailSender = ( String ) groupManager . readCustomAttr ( matchingGateway . getGroupId ( ) , EMAIL_SENDER_SITE_CUSTOM_FIELD ) ;
2019-07-22 17:24:10 +02:00
emailSender = emailSender . replace ( " \" " , " " ) ; //this is because otherwise it would contains double quotes and postfix would use it as first part before @ e.g. senderEmail="aginfra@d4science.org"@d4science.org
2019-04-05 16:39:46 +02:00
String siteLandingPagePath = GCubePortalConstants . PREFIX_GROUP_URL + matchingGateway . getFriendlyURL ( ) ;
String siteUrl = discoverHostOfServiceEndpoint ( siteName ) ;
SocialNetworkingSite site = new SocialNetworkingSite ( siteName , emailSender , siteUrl , siteLandingPagePath ) ;
logger . info ( " Site is " + site ) ;
return site ;
}
} catch ( Exception e ) {
logger . error ( " Failed to determine the SocialNetworkingSite for scope " + scope , e ) ;
}
return null ;
}
private static boolean isDevOrPreprod ( String rootContext ) {
2020-05-05 16:16:03 +02:00
return ( rootContext . equals ( " /gcube " ) | | rootContext . equals ( " /pred4s " ) ) ;
2019-04-05 16:39:46 +02:00
}
/ * *
* Retrieve endpoint host from IS for this gateway
* @return the host for the gateway
* @throws Exception
* /
private static String discoverHostOfServiceEndpoint ( String gatewayName ) {
String currentScope = ScopeProvider . instance . get ( ) ;
ApplicationContext ctx = ContextProvider . get ( ) ; // get this info from SmartGears
ScopeProvider . instance . set ( " / " + ctx . container ( ) . configuration ( ) . infrastructure ( ) ) ;
String host = null ;
try {
SimpleQuery query = queryFor ( ServiceEndpoint . class ) ;
query . addCondition ( " $resource/Profile/Name/text() eq ' " + gatewayName + " ' " ) ;
query . addCondition ( " $resource/Profile/Category/text() eq ' " + CATEGORY + " ' " ) ;
DiscoveryClient < ServiceEndpoint > client = clientFor ( ServiceEndpoint . class ) ;
List < ServiceEndpoint > toReturn = client . submit ( query ) ;
for ( ServiceEndpoint serviceEndpoint : toReturn ) {
host = " https:// " + serviceEndpoint . profile ( ) . runtime ( ) . hostedOn ( ) ;
logger . info ( " Gateway host is " + host ) ;
break ;
}
} catch ( Exception e ) {
logger . error ( " Error while retrieving host for the gateway " + gatewayName ) ;
} finally {
ScopeProvider . instance . set ( currentScope ) ;
}
return host ;
}
}