Implementing configuration management

This commit is contained in:
Luca Frosini 2022-02-15 21:18:02 +01:00
parent c8e383ea3c
commit 4df3e7cf5c
4 changed files with 142 additions and 115 deletions

View File

@ -45,14 +45,15 @@ public class GCoreISConfigurationProxy {
private static final Logger logger = LoggerFactory.getLogger(GCoreISConfigurationProxy.class);
// 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
private final static String IS_ROOT_MASTER_PROPERTY_KEY = "IS_ROOT_MASTER"; // true, false.. missing means false as
private final static String DEFAULT_ORGANIZATION_PROPERTY = "DEFAULT_ORGANIZATION";
private final static String SUPPORTED_ORGANIZATION_PROPERTY = "SUPPORTED_ORGANIZATION";
private final static String API_KEY_PROPERTY = "API_KEY";
private final static String SOCIAL_POST_PROPERTY = "SOCIAL_POST";
private final static String ALERT_USERS_ON_POST_CREATION_PROPERTY = "ALERT_USERS_ON_POST_CREATION";
private final static String MODERATION_ENABLED_KEY_PROPERTY = "MODERATION_ENABLED";
private final static String DEFAULT_ORGANIZATION_PROPERTY_KEY = "DEFAULT_ORGANIZATION";
private final static String SUPPORTED_ORGANIZATION_PROPERTY_KEY = "SUPPORTED_ORGANIZATION";
private final static String API_KEY_PROPERTY_KEY = "API_KEY";
private final static String SOLR_INDEX_ADDRESS_PROPERTY_KEY = "SOLR_INDEX_ADDRESS";
private final static String SOCIAL_POST_PROPERTY_KEY = "SOCIAL_POST";
private final static String ALERT_USERS_ON_POST_CREATION_PROPERTY_KEY = "ALERT_USERS_ON_POST_CREATION";
private final static String MODERATION_ENABLED_KEY_PROPERTY_KEY = "MODERATION_ENABLED";
// CKAN Instance info
private final static String CATEGORY = "Application";
@ -108,30 +109,37 @@ public class GCoreISConfigurationProxy {
Map<String, Property> propertyMap = accessPoint.propertyMap();
// retrieve sys admin token
String sysAdminToken = propertyMap.get(API_KEY_PROPERTY).value();
String sysAdminToken = propertyMap.get(API_KEY_PROPERTY_KEY).value();
sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken);
catalogueConfiguration.setSysAdminToken(sysAdminToken);
String organization = CatalogueConfiguration.getOrganizationName(context);
if (propertyMap.containsKey(DEFAULT_ORGANIZATION_PROPERTY)) {
String org = propertyMap.get(DEFAULT_ORGANIZATION_PROPERTY).value().trim();
String defaultOrganization = CatalogueConfiguration.getOrganizationName(context);
if (propertyMap.containsKey(DEFAULT_ORGANIZATION_PROPERTY_KEY)) {
String org = propertyMap.get(DEFAULT_ORGANIZATION_PROPERTY_KEY).value().trim();
if(org!=null && org.compareTo("")==0) {
mustBeUpdated = true;
}else {
organization = org;
defaultOrganization = org;
}
}else {
mustBeUpdated = true;
}
catalogueConfiguration.setOrganization(organization);
catalogueConfiguration.setDefaultOrganization(defaultOrganization);
String solrURL = null;
if (propertyMap.containsKey(SOLR_INDEX_ADDRESS_PROPERTY_KEY)) {
solrURL = propertyMap.get(SOLR_INDEX_ADDRESS_PROPERTY_KEY).value();
catalogueConfiguration.setSolrURL(solrURL);
}
// retrieve option to check if the social post has to be made
Boolean socialPostEnabled = true;
if (propertyMap.containsKey(SOCIAL_POST_PROPERTY)) {
if (propertyMap.get(SOCIAL_POST_PROPERTY).value().trim().equalsIgnoreCase("false")) {
if (propertyMap.containsKey(SOCIAL_POST_PROPERTY_KEY)) {
if (propertyMap.get(SOCIAL_POST_PROPERTY_KEY).value().trim().equalsIgnoreCase("false")) {
socialPostEnabled = false;
}
}else {
@ -141,8 +149,8 @@ public class GCoreISConfigurationProxy {
// retrieve option for user alert
boolean notificationToUsersEnabled = false; // default is false
if (propertyMap.containsKey(ALERT_USERS_ON_POST_CREATION_PROPERTY)) {
if (propertyMap.get(ALERT_USERS_ON_POST_CREATION_PROPERTY).value().trim()
if (propertyMap.containsKey(ALERT_USERS_ON_POST_CREATION_PROPERTY_KEY)) {
if (propertyMap.get(ALERT_USERS_ON_POST_CREATION_PROPERTY_KEY).value().trim()
.equalsIgnoreCase("true")) {
notificationToUsersEnabled = true;
}
@ -152,8 +160,8 @@ public class GCoreISConfigurationProxy {
catalogueConfiguration.setNotificationToUsersEnabled(notificationToUsersEnabled);
boolean moderationEnabled = false; // default is false
if (propertyMap.containsKey(MODERATION_ENABLED_KEY_PROPERTY)) {
if (propertyMap.get(MODERATION_ENABLED_KEY_PROPERTY).value().trim().equalsIgnoreCase("true")) {
if (propertyMap.containsKey(MODERATION_ENABLED_KEY_PROPERTY_KEY)) {
if (propertyMap.get(MODERATION_ENABLED_KEY_PROPERTY_KEY).value().trim().equalsIgnoreCase("true")) {
moderationEnabled = true;
}
}else {
@ -162,8 +170,8 @@ public class GCoreISConfigurationProxy {
catalogueConfiguration.setModerationEnabled(moderationEnabled);
Set<String> supportedOrganizations = null;
if (propertyMap.containsKey(SUPPORTED_ORGANIZATION_PROPERTY)) {
String jsonArray = propertyMap.get(SUPPORTED_ORGANIZATION_PROPERTY).value();
if (propertyMap.containsKey(SUPPORTED_ORGANIZATION_PROPERTY_KEY)) {
String jsonArray = propertyMap.get(SUPPORTED_ORGANIZATION_PROPERTY_KEY).value();
supportedOrganizations = unmarshallSupportedOrganizations(jsonArray);
removeAllGenericResources();
}else {
@ -196,7 +204,7 @@ public class GCoreISConfigurationProxy {
*/
private List<ServiceEndpoint> getServiceEndpoints() {
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Category/Name/text() eq '" + CATEGORY + "'");
query.addCondition("$resource/Profile/Category/text() eq '" + CATEGORY + "'");
query.addCondition("$resource/Profile/Name/text() eq '" + NAME + "'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
@ -217,7 +225,7 @@ public class GCoreISConfigurationProxy {
if (serviceEndpoints.size() > 1) {
logger.info("Too many {} having Category {} and Name {} in this context. Looking for the one that has the property {}",
ServiceEndpoint.class.getSimpleName(), CATEGORY, NAME, IS_MASTER_ROOT_KEY_PROPERTY);
ServiceEndpoint.class.getSimpleName(), CATEGORY, NAME, IS_ROOT_MASTER_PROPERTY_KEY);
for (ServiceEndpoint se : serviceEndpoints) {
Iterator<AccessPoint> accessPointIterator = se.profile().accessPoints().iterator();
@ -225,7 +233,7 @@ public class GCoreISConfigurationProxy {
ServiceEndpoint.AccessPoint accessPoint = accessPointIterator.next();
// get the is master property
Property entry = accessPoint.propertyMap().get(IS_MASTER_ROOT_KEY_PROPERTY);
Property entry = accessPoint.propertyMap().get(IS_ROOT_MASTER_PROPERTY_KEY);
String isMaster = entry != null ? entry.value() : null;
if (isMaster == null || !isMaster.equals("true")) {
@ -363,7 +371,7 @@ public class GCoreISConfigurationProxy {
return property;
}
protected AccessPoint setAccessPointProperties(AccessPoint accessPoint, boolean update) throws JsonProcessingException {
protected Group<Property> setAccessPointProperties(AccessPoint accessPoint, boolean update) throws JsonProcessingException {
accessPoint.description(String.format("Access Point %s by gcat %s", update ? "updated" : "created", getGcatVersion().toString()));
accessPoint.address(catalogueConfiguration.getCkanURL());
@ -372,14 +380,15 @@ public class GCoreISConfigurationProxy {
accessPoint.name("CKan Data Catalogue");
Group<Property> properties = accessPoint.properties();
addProperty(properties, DEFAULT_ORGANIZATION_PROPERTY, catalogueConfiguration.getOrganization());
addProperty(properties, API_KEY_PROPERTY, catalogueConfiguration.getSysAdminToken(), true);
addProperty(properties, SOCIAL_POST_PROPERTY, Boolean.toString(catalogueConfiguration.isSocialPostEnabled()));
addProperty(properties, ALERT_USERS_ON_POST_CREATION_PROPERTY, Boolean.toString(catalogueConfiguration.isNotificationToUsersEnabled()));
addProperty(properties, MODERATION_ENABLED_KEY_PROPERTY, Boolean.toString(catalogueConfiguration.isModerationEnabled()));
addProperty(properties, SUPPORTED_ORGANIZATION_PROPERTY, marshallSupportedOrganizations());
addProperty(properties, SOLR_INDEX_ADDRESS_PROPERTY_KEY, catalogueConfiguration.getSolrURL());
addProperty(properties, DEFAULT_ORGANIZATION_PROPERTY_KEY, catalogueConfiguration.getDefaultOrganization());
addProperty(properties, API_KEY_PROPERTY_KEY, catalogueConfiguration.getSysAdminToken(), true);
addProperty(properties, SOCIAL_POST_PROPERTY_KEY, Boolean.toString(catalogueConfiguration.isSocialPostEnabled()));
addProperty(properties, ALERT_USERS_ON_POST_CREATION_PROPERTY_KEY, Boolean.toString(catalogueConfiguration.isNotificationToUsersEnabled()));
addProperty(properties, MODERATION_ENABLED_KEY_PROPERTY_KEY, Boolean.toString(catalogueConfiguration.isModerationEnabled()));
addProperty(properties, SUPPORTED_ORGANIZATION_PROPERTY_KEY, marshallSupportedOrganizations());
return accessPoint;
return properties;
}
private final static String PLATFORM_NAME = "Tomcat";
@ -455,25 +464,40 @@ public class GCoreISConfigurationProxy {
return profile;
}
protected boolean isRootMaster(ServiceEndpoint serviceEndpoint) {
Profile profile = serviceEndpoint.profile();
AccessPoint accessPoint = getAccessPoint(profile);
Map<String, Property> propertyMap = accessPoint.propertyMap();
if (propertyMap.containsKey(IS_ROOT_MASTER_PROPERTY_KEY)) {
if (propertyMap.get(IS_ROOT_MASTER_PROPERTY_KEY).value().trim().equalsIgnoreCase("true")) {
return true;
}
}
return false;
}
protected ServiceEndpoint createServiceEndpoint(ServiceEndpoint serviceEndpoint) throws Exception {
boolean update = serviceEndpoint != null;
boolean rootMaster = false;
if(update) {
if(catalogueConfiguration.getSysAdminToken()==null) {
Profile profile = serviceEndpoint.profile();
AccessPoint accessPoint = getAccessPoint(profile);
Map<String, Property> propertyMap = accessPoint.propertyMap();
// add this host
String ckanURL = accessPoint.address();
catalogueConfiguration.setCkanURL(ckanURL);
Map<String, Property> propertyMap = accessPoint.propertyMap();
// retrieve sys admin token
String sysAdminToken = propertyMap.get(API_KEY_PROPERTY).value();
String sysAdminToken = propertyMap.get(API_KEY_PROPERTY_KEY).value();
sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken);
catalogueConfiguration.setSysAdminToken(sysAdminToken);
}
rootMaster = isRootMaster(serviceEndpoint);
}
@ -491,7 +515,11 @@ public class GCoreISConfigurationProxy {
Group<AccessPoint> accessPoints = profile.accessPoints();
AccessPoint accessPoint = accessPoints.add();
setAccessPointProperties(accessPoint, update);
Group<Property> properties = setAccessPointProperties(accessPoint, update);
if(rootMaster) {
addProperty(properties, IS_ROOT_MASTER_PROPERTY_KEY, Boolean.toString(rootMaster));
}
return serviceEndpoint;
}

View File

@ -170,7 +170,7 @@ public class CKANPackage extends CKAN implements Moderated {
if(ckanOrganization == null) {
// owner organization must be specified if the token belongs to a VRE
String organizationFromContext = configuration.getOrganization();
String organizationFromContext = configuration.getDefaultOrganization();
ckanOrganization = checkGotOrganization(organizationFromContext);
objectNode.put(OWNER_ORG_KEY, organizationFromContext);
}

View File

@ -60,10 +60,10 @@ public class Configuration extends BaseREST implements org.gcube.gcat.api.interf
return c;
}
private String createOrUpdate(ObjectMapper mapper, CatalogueConfiguration catalogueConfiguration) throws WebServiceException {
private String createOrUpdate(CatalogueConfiguration catalogueConfiguration) throws WebServiceException {
try {
CatalogueConfiguration gotCatalogueConfiguration = CatalogueConfigurationFactory.createOrUpdate(catalogueConfiguration);
String configuration = mapper.writeValueAsString(gotCatalogueConfiguration);
String configuration = gotCatalogueConfiguration.toJsonString();
logger.debug("The new configuration in context {} is {}", catalogueConfiguration.getContext(), configuration);
return configuration;
}catch (WebServiceException e) {
@ -82,7 +82,7 @@ public class Configuration extends BaseREST implements org.gcube.gcat.api.interf
ObjectMapper mapper = new ObjectMapper();
CatalogueConfiguration catalogueConfiguration = mapper.readValue(json, CatalogueConfiguration.class);
checkContext(context, catalogueConfiguration);
return createOrUpdate(mapper, catalogueConfiguration);
return createOrUpdate(catalogueConfiguration);
}catch (WebServiceException e) {
throw e;
}catch (Exception e) {
@ -100,7 +100,7 @@ public class Configuration extends BaseREST implements org.gcube.gcat.api.interf
ObjectMapper mapper = new ObjectMapper();
CatalogueConfiguration catalogueConfiguration = mapper.readValue(json, CatalogueConfiguration.class);
checkContext(CURRENT_CONTEXT_PATH_PARAMETER, catalogueConfiguration);
String ret = createOrUpdate(mapper, catalogueConfiguration);
String ret = createOrUpdate(catalogueConfiguration);
ResponseBuilder responseBuilder = Response.status(Status.CREATED);
if(ret!=null) {
responseBuilder.entity(ret).type(ResourceInitializer.APPLICATION_JSON_CHARSET_UTF_8);
@ -188,7 +188,7 @@ public class Configuration extends BaseREST implements org.gcube.gcat.api.interf
node.remove(CURRENT_CONTEXT_PATH_PARAMETER);
}
ObjectNode configuration = mapper.valueToTree(catalogueConfiguration);
ObjectNode configuration = catalogueConfiguration.toObjetNode();
Iterator<String> fieldNames = node.fieldNames();
while(fieldNames.hasNext()) {

View File

@ -1,21 +1,10 @@
package org.gcube.gcat.configuration;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.common.authorization.utils.manager.SecretManager;
import org.gcube.common.resources.gcore.GenericResource;
import org.gcube.common.resources.gcore.Resources;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.gcat.ContextTest;
import org.gcube.gcat.api.configuration.CatalogueConfiguration;
import org.gcube.informationsystem.publisher.RegistryPublisher;
import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
@ -34,69 +23,79 @@ public class GCoreISConfigurationProxyTest extends ContextTest {
Assert.assertTrue(organizations.size()>0);
}
protected GenericResource instantiateGenericResource(String secondaryType, String name, String xml) throws Exception {
GenericResource genericResource = new GenericResource();
org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile();
profile.type(secondaryType);
profile.name(name);
profile.description("This resource is read by gCat and define the list of CKAN organizations where a client is allowed to publish for the current context");
profile.newBody(xml);
StringWriter stringWriter = new StringWriter();
Resources.marshal(genericResource, stringWriter);
logger.debug("The generated {} is\n{}", GenericResource.class.getSimpleName(), stringWriter.toString());
return genericResource;
@Test
public void testCatalogueConfiguration() throws Exception {
ContextTest.setContextByName("/gcube/devsec");
String context = SecretManager.instance.get().getContext();
GCoreISConfigurationProxy gCoreISConfigurationProxy = new GCoreISConfigurationProxy(context);
CatalogueConfiguration catalogueConfiguration = gCoreISConfigurationProxy.getCatalogueConfigurationFromIS();
logger.info("Configuration inn context {} is {}", context, catalogueConfiguration.toJsonString());
}
protected void createGenericResource(String xml) throws Exception {
GenericResource genericResource = instantiateGenericResource(
GCoreISConfigurationProxy.GENERIC_RESOURCE_SECONDARY_TYPE_FOR_ORGANIZATIONS,
GCoreISConfigurationProxy.GENERIC_RESOURCE_NAME_FOR_ORGANIZATIONS, xml);
RegistryPublisher registryPublisher = RegistryPublisherFactory.create();
genericResource = registryPublisher.create(genericResource);
StringWriter stringWriter = new StringWriter();
Resources.marshal(genericResource, stringWriter);
logger.trace("The {} with ID {} has been created \n{}", GenericResource.class.getSimpleName(),
genericResource.id(), stringWriter.toString());
}
protected String createGRBody(List<String> organizations) throws Exception {
if(organizations==null || organizations.size()<1) {
throw new Exception("Unable to create the body for the generic resource with empty organization list");
}
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = objectMapper.createObjectNode();
ArrayNode arrayNode = objectNode.putArray(GCoreISConfigurationProxy.GENERIC_RESOURCE_CKAN_ORGANIZATIONS);
for(String organizationName : organizations) {
arrayNode.add(organizationName);
}
return objectMapper.writeValueAsString(objectNode);
}
protected void createGenericResourceForSupportedOrganizations(List<String> organizations) throws Exception {
String json = createGRBody(organizations);
createGenericResource(json);
}
// @Test
public void createGenericResourceForSupportedOrganizationsByName() throws Exception {
List<String> organizations = new ArrayList<>();
organizations.add("nextnext");
organizations.add("devvre");
createGenericResourceForSupportedOrganizations(organizations);
}
// @Test
public void createGenericResourceForSupportedOrganizationsByScopeBean() throws Exception {
ContextTest.setContextByName("/gcube/devNext/NextNext");
List<ScopeBean> scopeBeans = new ArrayList<>();
scopeBeans.add(new ScopeBean("/gcube/devNext/NextNext"));
scopeBeans.add(new ScopeBean("/gcube/devsec/devVRE"));
List<String> organizations = new ArrayList<>();
for(ScopeBean scopeBean : scopeBeans) {
organizations.add(CatalogueConfiguration.getOrganizationName(scopeBean));
}
createGenericResourceForSupportedOrganizations(organizations);
}
// protected GenericResource instantiateGenericResource(String secondaryType, String name, String xml) throws Exception {
// GenericResource genericResource = new GenericResource();
// org.gcube.common.resources.gcore.GenericResource.Profile profile = genericResource.newProfile();
// profile.type(secondaryType);
// profile.name(name);
// profile.description("This resource is read by gCat and define the list of CKAN organizations where a client is allowed to publish for the current context");
// profile.newBody(xml);
// StringWriter stringWriter = new StringWriter();
// Resources.marshal(genericResource, stringWriter);
// logger.debug("The generated {} is\n{}", GenericResource.class.getSimpleName(), stringWriter.toString());
// return genericResource;
// }
//
// protected void createGenericResource(String xml) throws Exception {
// GenericResource genericResource = instantiateGenericResource(
// GCoreISConfigurationProxy.GENERIC_RESOURCE_SECONDARY_TYPE_FOR_ORGANIZATIONS,
// GCoreISConfigurationProxy.GENERIC_RESOURCE_NAME_FOR_ORGANIZATIONS, xml);
// RegistryPublisher registryPublisher = RegistryPublisherFactory.create();
// genericResource = registryPublisher.create(genericResource);
// StringWriter stringWriter = new StringWriter();
// Resources.marshal(genericResource, stringWriter);
// logger.trace("The {} with ID {} has been created \n{}", GenericResource.class.getSimpleName(),
// genericResource.id(), stringWriter.toString());
// }
//
// protected String createGRBody(List<String> organizations) throws Exception {
// if(organizations==null || organizations.size()<1) {
// throw new Exception("Unable to create the body for the generic resource with empty organization list");
// }
// ObjectMapper objectMapper = new ObjectMapper();
// ObjectNode objectNode = objectMapper.createObjectNode();
// ArrayNode arrayNode = objectNode.putArray(GCoreISConfigurationProxy.GENERIC_RESOURCE_CKAN_ORGANIZATIONS);
// for(String organizationName : organizations) {
// arrayNode.add(organizationName);
// }
// return objectMapper.writeValueAsString(objectNode);
// }
//
// protected void createGenericResourceForSupportedOrganizations(List<String> organizations) throws Exception {
// String json = createGRBody(organizations);
// createGenericResource(json);
// }
//
// // @Test
// public void createGenericResourceForSupportedOrganizationsByName() throws Exception {
// List<String> organizations = new ArrayList<>();
// organizations.add("nextnext");
// organizations.add("devvre");
// createGenericResourceForSupportedOrganizations(organizations);
// }
//
// // @Test
// public void createGenericResourceForSupportedOrganizationsByScopeBean() throws Exception {
// ContextTest.setContextByName("/gcube/devNext/NextNext");
//
// List<ScopeBean> scopeBeans = new ArrayList<>();
// scopeBeans.add(new ScopeBean("/gcube/devNext/NextNext"));
// scopeBeans.add(new ScopeBean("/gcube/devsec/devVRE"));
// List<String> organizations = new ArrayList<>();
// for(ScopeBean scopeBean : scopeBeans) {
// organizations.add(CatalogueConfiguration.getOrganizationName(scopeBean));
// }
// createGenericResourceForSupportedOrganizations(organizations);
// }
}