298 lines
10 KiB
Java
298 lines
10 KiB
Java
package org.gcube.gcat.persistence.ckan;
|
|
|
|
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
|
|
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import javax.ws.rs.InternalServerErrorException;
|
|
import javax.ws.rs.WebApplicationException;
|
|
|
|
import org.gcube.com.fasterxml.jackson.databind.JsonNode;
|
|
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
|
|
import org.gcube.common.authorization.utils.manager.SecretManager;
|
|
import org.gcube.common.encryption.encrypter.StringEncrypter;
|
|
import org.gcube.common.resources.gcore.GenericResource;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
|
|
import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
|
|
import org.gcube.common.scope.impl.ScopeBean;
|
|
import org.gcube.resources.discovery.client.api.DiscoveryClient;
|
|
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
|
|
import org.gcube.resources.discovery.icclient.ICFactory;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
*/
|
|
public class CKANInstance {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(CKANInstance.class);
|
|
|
|
// CKAN Instance info
|
|
private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue";
|
|
private final static String PLATFORM_CATALOGUE_NAME = "Tomcat";
|
|
|
|
// property to retrieve the master service endpoint into the /root scope
|
|
private final static String IS_MASTER_ROOT_KEY_PROPERTY = "IS_ROOT_MASTER"; // true, false.. missing means false as well
|
|
|
|
private final static String API_KEY_PROPERTY = "API_KEY";
|
|
private final static String SOCIAL_POST = "SOCIAL_POST";
|
|
private final static String ALERT_USERS_ON_POST_CREATION = "ALERT_USERS_ON_POST_CREATION";
|
|
private final static String URL_RESOLVER = "URL_RESOLVER";
|
|
private final static String MODERATION_ENABLED_KEY = "MODERATION_ENABLED";
|
|
|
|
private static final Map<String,CKANInstance> ckanInstancePerScope;
|
|
|
|
protected String ckanURL;
|
|
protected String sysAdminToken;
|
|
protected boolean socialPostEnabled;
|
|
protected Boolean notificationToUsersEnabled;
|
|
protected String uriResolverURL;
|
|
|
|
protected boolean moderationEnabled;
|
|
|
|
protected final String currentContext;
|
|
protected final ScopeBean currentScopeBean;
|
|
|
|
protected final String currentOrganizationName;
|
|
protected final Set<String> supportedOrganizations;
|
|
|
|
|
|
static {
|
|
ckanInstancePerScope = new HashMap<String,CKANInstance>();
|
|
}
|
|
|
|
public static CKANInstance getInstance() {
|
|
String context = SecretManager.instance.get().getContext();
|
|
CKANInstance ckanInstance = ckanInstancePerScope.get(context);
|
|
if(ckanInstance == null) {
|
|
ckanInstance = new CKANInstance();
|
|
ckanInstance.getConfigurationFromIS();
|
|
ckanInstancePerScope.put(context, ckanInstance);
|
|
}
|
|
return ckanInstance;
|
|
}
|
|
|
|
|
|
private CKANInstance() {
|
|
currentContext = SecretManager.instance.get().getContext();
|
|
currentScopeBean = new ScopeBean(currentContext);
|
|
currentOrganizationName = CKANPackage.getOrganizationName(currentScopeBean);
|
|
supportedOrganizations = getSupportedOrganizationsFromIS();
|
|
}
|
|
|
|
/**
|
|
* Retrieve endpoints information from IS for DataCatalogue URL
|
|
* @return list of endpoints for ckan data catalogue
|
|
* @throws Exception
|
|
*/
|
|
private static List<ServiceEndpoint> getServiceEndpoints() {
|
|
SimpleQuery query = queryFor(ServiceEndpoint.class);
|
|
query.addCondition("$resource/Profile/Name/text() eq '" + RUNTIME_CATALOGUE_RESOURCE_NAME + "'");
|
|
query.addCondition("$resource/Profile/Platform/Name/text() eq '" + PLATFORM_CATALOGUE_NAME + "'");
|
|
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
|
|
List<ServiceEndpoint> serviceEndpoints = client.submit(query);
|
|
if(serviceEndpoints.size() == 0) {
|
|
logger.error("There is no {} having name {} and Platform {} in this context.",
|
|
ServiceEndpoint.class.getSimpleName(), RUNTIME_CATALOGUE_RESOURCE_NAME, PLATFORM_CATALOGUE_NAME);
|
|
throw new InternalServerErrorException("No CKAN configuration on IS");
|
|
}
|
|
return serviceEndpoints;
|
|
}
|
|
|
|
private void getConfigurationFromIS() {
|
|
try {
|
|
List<ServiceEndpoint> serviceEndpoints = getServiceEndpoints();
|
|
ServiceEndpoint serviceEndpoint = null;
|
|
|
|
if(serviceEndpoints.size() > 1) {
|
|
logger.info("Too many {} having name {} in this context. Looking for the one that has the property {}",
|
|
ServiceEndpoint.class.getSimpleName(), RUNTIME_CATALOGUE_RESOURCE_NAME,
|
|
IS_MASTER_ROOT_KEY_PROPERTY);
|
|
|
|
for(ServiceEndpoint se : serviceEndpoints) {
|
|
Iterator<AccessPoint> accessPointIterator = se.profile().accessPoints().iterator();
|
|
while(accessPointIterator.hasNext()) {
|
|
ServiceEndpoint.AccessPoint accessPoint = accessPointIterator.next();
|
|
|
|
// get the is master property
|
|
Property entry = accessPoint.propertyMap().get(IS_MASTER_ROOT_KEY_PROPERTY);
|
|
String isMaster = entry != null ? entry.value() : null;
|
|
|
|
if(isMaster == null || !isMaster.equals("true")) {
|
|
continue;
|
|
}
|
|
|
|
// set this variable
|
|
serviceEndpoint = se;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if none of them was master, throw an exception
|
|
if(serviceEndpoint == null) {
|
|
throw new InternalServerErrorException(
|
|
"Too many CKAN configuration on IS and no one with MASTER property");
|
|
}
|
|
|
|
} else {
|
|
serviceEndpoint = serviceEndpoints.get(0);
|
|
}
|
|
|
|
Iterator<AccessPoint> accessPointIterator = serviceEndpoint.profile().accessPoints().iterator();
|
|
while(accessPointIterator.hasNext()) {
|
|
AccessPoint accessPoint = accessPointIterator.next();
|
|
|
|
// add this host
|
|
ckanURL = accessPoint.address();
|
|
|
|
// retrieve sys admin token
|
|
sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value();
|
|
sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken);
|
|
|
|
// retrieve option to check if the social post has to be made
|
|
socialPostEnabled = true; // default is true
|
|
if(accessPoint.propertyMap().containsKey(SOCIAL_POST)) {
|
|
if(accessPoint.propertyMap().get(SOCIAL_POST).value().trim().equalsIgnoreCase("false")) {
|
|
socialPostEnabled = false;
|
|
}
|
|
}
|
|
|
|
// retrieve option for user alert
|
|
notificationToUsersEnabled = false;
|
|
if(accessPoint.propertyMap().containsKey(ALERT_USERS_ON_POST_CREATION)) {
|
|
if(accessPoint.propertyMap().get(ALERT_USERS_ON_POST_CREATION).value().trim()
|
|
.equalsIgnoreCase("true")) {
|
|
notificationToUsersEnabled = true;
|
|
}
|
|
}
|
|
|
|
// retrieve URL_RESOLVER
|
|
if(accessPoint.propertyMap().containsKey(URL_RESOLVER)) {
|
|
uriResolverURL = accessPoint.propertyMap().get(URL_RESOLVER).value();
|
|
}
|
|
|
|
|
|
moderationEnabled = false;
|
|
if(accessPoint.propertyMap().containsKey(MODERATION_ENABLED_KEY)) {
|
|
if(accessPoint.propertyMap().get(MODERATION_ENABLED_KEY).value().trim()
|
|
.equalsIgnoreCase("true")) {
|
|
moderationEnabled = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
} catch(WebApplicationException e) {
|
|
throw e;
|
|
} catch(Exception e) {
|
|
throw new InternalServerErrorException("Error while getting configuration on IS", e);
|
|
}
|
|
|
|
}
|
|
|
|
public static final String GENERIC_RESOURCE_SECONDARY_TYPE_FOR_ORGANIZATIONS = "ApplicationProfile";
|
|
public static final String GENERIC_RESOURCE_NAME_FOR_ORGANIZATIONS = "Supported CKAN Organizations";
|
|
public static final String GENERIC_RESOURCE_CKAN_ORGANIZATIONS = "CKANOrganizations";
|
|
|
|
protected Set<String> getSupportedOrganizationsFromIS() {
|
|
Set<String> supportedOrganizations = new HashSet<>();
|
|
|
|
SimpleQuery query = ICFactory.queryFor(GenericResource.class);
|
|
query.addCondition(String.format("$resource/Profile/SecondaryType/text() eq '%s'",
|
|
GENERIC_RESOURCE_SECONDARY_TYPE_FOR_ORGANIZATIONS));
|
|
query.addCondition(
|
|
String.format("$resource/Profile/Name/text() eq '%s'", GENERIC_RESOURCE_NAME_FOR_ORGANIZATIONS));
|
|
|
|
DiscoveryClient<GenericResource> client = ICFactory.clientFor(GenericResource.class);
|
|
List<GenericResource> resources = client.submit(query);
|
|
|
|
if(resources == null || resources.size() == 0) {
|
|
logger.info(
|
|
"{} with SecondaryType {} and Name %s not found. Item will be only be created in {} CKAN organization",
|
|
GenericResource.class.getSimpleName(), GENERIC_RESOURCE_SECONDARY_TYPE_FOR_ORGANIZATIONS,
|
|
GENERIC_RESOURCE_NAME_FOR_ORGANIZATIONS, currentOrganizationName);
|
|
supportedOrganizations.add(currentOrganizationName);
|
|
} else {
|
|
try {
|
|
GenericResource genericResource = resources.get(0);
|
|
String body = genericResource.profile().body().getTextContent();
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
JsonNode jsonNode = objectMapper.readTree(body);
|
|
ArrayNode array = (ArrayNode) jsonNode.get(GENERIC_RESOURCE_CKAN_ORGANIZATIONS);
|
|
for(int i = 0; i < array.size(); i++) {
|
|
String organization = array.get(i).asText();
|
|
supportedOrganizations.add(organization);
|
|
}
|
|
}catch (Exception e) {
|
|
supportedOrganizations.clear();
|
|
supportedOrganizations.add(currentOrganizationName);
|
|
}
|
|
}
|
|
|
|
logger.debug("Supported CKAN Organization for current Context ({}) are {}", currentContext,
|
|
supportedOrganizations);
|
|
|
|
return supportedOrganizations;
|
|
}
|
|
|
|
|
|
public String getUriResolverURL() throws Exception {
|
|
return uriResolverURL;
|
|
}
|
|
|
|
public String getCKANURL() {
|
|
return ckanURL;
|
|
}
|
|
|
|
public boolean isSocialPostEnabled() throws Exception {
|
|
return socialPostEnabled;
|
|
}
|
|
|
|
public boolean isNotificationToUsersEnabled() throws Exception {
|
|
return notificationToUsersEnabled;
|
|
}
|
|
|
|
public boolean isModerationEnabled() {
|
|
return moderationEnabled;
|
|
}
|
|
|
|
public String getSysAdminToken() throws Exception {
|
|
return sysAdminToken;
|
|
}
|
|
|
|
|
|
public String getCurrentContext() {
|
|
return currentContext;
|
|
}
|
|
|
|
|
|
public ScopeBean getCurrentScopeBean() {
|
|
return currentScopeBean;
|
|
}
|
|
|
|
|
|
public String getCurrentOrganizationName() {
|
|
return currentOrganizationName;
|
|
}
|
|
|
|
|
|
public Set<String> getSupportedOrganizations() {
|
|
return supportedOrganizations;
|
|
}
|
|
|
|
|
|
public void setModerationEnabled(boolean moderationEnabled) {
|
|
this.moderationEnabled = moderationEnabled;
|
|
}
|
|
|
|
}
|