diff --git a/distro/changelog.xml b/distro/changelog.xml
index dc4af9f..9c92636 100644
--- a/distro/changelog.xml
+++ b/distro/changelog.xml
@@ -63,7 +63,8 @@
+ date="2017-02-28">
[Task #6492] Catalogue Resolver: "improve"/"build better" public URLs to products
+ [Task #6952] Catalogue Resolver: update on the fly the Application Profile for VRE's used to resolve Product URL
\ No newline at end of file
diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java
index 2c39b44..3bf675b 100644
--- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java
+++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/CatalogueResolver.java
@@ -19,6 +19,10 @@ import org.gcube.common.encryption.StringEncrypter;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.datatransfer.resolver.ResourceCatalogueCodes;
import org.gcube.datatransfer.resolver.UriResolverRewriteFilter;
+import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException;
+import org.gcube.datatransfer.resolver.catalogue.resource.ApplicationProfileReaderForCatalogueResolver;
+import org.gcube.datatransfer.resolver.catalogue.resource.CkanPorltetApplicationProfile;
+import org.gcube.datatransfer.resolver.catalogue.resource.UpdateApplicationProfileCatalogueResolver;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -210,7 +214,7 @@ public class CatalogueResolver extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- CatalogueEntityRequest cer = new CatalogueEntityRequest();
+ final CatalogueEntityRequest cer = new CatalogueEntityRequest();
String originalScope = null;
try{
String jsonRequest = IOUtils.toString(req.getInputStream());
@@ -289,7 +293,7 @@ public class CatalogueResolver extends HttpServlet{
logger.info("Clear URL is: "+bClearURL);
if(bClearURL){
- String vreName = scope.substring(scope.lastIndexOf("/")+1, scope.length());
+ final String vreName = scope.substring(scope.lastIndexOf("/")+1, scope.length());
//buildLink+=PATH_SEPARATOR+vreName+PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_CONTEXT.getKey())+PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey());
String econtext = cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_CONTEXT.getKey());
ResourceCatalogueCodes rc = ResourceCatalogueCodes.valueOfCodeValue(econtext);
@@ -300,6 +304,21 @@ public class CatalogueResolver extends HttpServlet{
}
buildLink += PATH_SEPARATOR+rc.getId()+PATH_SEPARATOR+vreName+PATH_SEPARATOR+cer.getValueOfParameter(CatalogueRequestParameter.ENTITY_NAME.getKey());
logger.info("Writing Decoded Catalogue Link: "+buildLink);
+
+ //IT'S GOING TO UPDATE THE GENERIC RESOURCE IF IS NEEDED
+ new Thread(){
+ public void run() {
+ try {
+ String fullScope = cer.getValueOfParameter(CatalogueRequestParameter.GCUBE_SCOPE.getKey());
+ UpdateApplicationProfileCatalogueResolver.validateEndPoint(scopeToEncDecr, vreName, fullScope);
+ }
+ catch (ApplicationProfileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ };
+ }.start();
+
}else{
//ADDING THE SERVLET NAME
buildLink += req.getRequestURI();
diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/ApplicationProfileReaderForCatalogueResolver.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/ApplicationProfileReaderForCatalogueResolver.java
similarity index 83%
rename from src/main/java/org/gcube/datatransfer/resolver/catalogue/ApplicationProfileReaderForCatalogueResolver.java
rename to src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/ApplicationProfileReaderForCatalogueResolver.java
index 1099e39..44542c6 100644
--- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/ApplicationProfileReaderForCatalogueResolver.java
+++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/ApplicationProfileReaderForCatalogueResolver.java
@@ -1,7 +1,7 @@
/*
*
*/
-package org.gcube.datatransfer.resolver.catalogue;
+package org.gcube.datatransfer.resolver.catalogue.resource;
import static org.gcube.resources.discovery.icclient.ICFactory.client;
@@ -23,7 +23,8 @@ import org.gcube.datatransfer.resolver.applicationprofile.ScopeUtil;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.Query;
import org.gcube.resources.discovery.client.queries.impl.QueryBox;
-import org.w3c.dom.Node;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.xml.sax.InputSource;
@@ -35,24 +36,33 @@ import org.xml.sax.InputSource;
*/
public class ApplicationProfileReaderForCatalogueResolver {
+ public static final String VRE_NAME = "VRE_NAME";
+ public static final String SCOPE = "SCOPE";
+ public static final String END_POINT = "EndPoint";
+ public static final String BODY = "Body";
+
+
public static final String SECONDARY_TYPE = "ApplicationProfile";
public static final String RESOURCE_NAME = "Catalogue-Resolver";
protected static final String RESOURCE_PROFILE_NAME_TEXT = "/Resource/Profile/Name/text()";
protected static final String RESOURCE_PROFILE_DESCRIPTION_TEXT = "/Resource/Profile/Description/text()";
- protected static final String RESOURCE_PROFILE_BODY_END_POINT_SCOPE_TEXT = "/Resource/Profile/Body/EndPoint/SCOPE/text()";
- protected static final String RESOURCE_PROFILE_BODY_END_POINT_VRE_NAME_TEXT = "/Resource/Profile/Body/EndPoint/VRE_NAME/text()";
+ protected static final String RESOURCE_PROFILE_BODY_END_POINT_SCOPE_TEXT = "/Resource/Profile/"+BODY+"/"+END_POINT+"/"+SCOPE+"/text()";
+ protected static final String RESOURCE_PROFILE_BODY_END_POINT_VRE_NAME_TEXT = "/Resource/Profile/"+BODY+"/"+END_POINT+"/"+VRE_NAME+"/text()";
+
private Logger logger = Logger.getLogger(ApplicationProfileReaderForCatalogueResolver.class);
private String secondaryType;
private String resourceName;
private String scope;
private boolean useRootScope = false;
+ private Document document;
/** The hash vre name scope.
* Used by Catalogue Resolver for mapping VRE NAME with its SCOPE where to fetch the Data Catalogue Portlet so that resolve correctly URL of
* kind: http://[CATALOGUE_RESOLVER_SERVLET]/[VRE_NAME]/[entity_context value]/[entity_name value]
* */
private Map hashVreNameScope = new HashMap();
+ private Element rootElement;
/**
* Instantiates a new application profile reader for catalogue resolver.
@@ -69,7 +79,7 @@ public class ApplicationProfileReaderForCatalogueResolver {
}
/**
- * Read profile from infrastrucure and fills the map {@link #hashVreNameScope}
+ * Read profile from infrastrucure and fills the map {@link #hashVreNameScope}.
*/
private void readProfileFromInfrastrucure() {
@@ -91,9 +101,10 @@ public class ApplicationProfileReaderForCatalogueResolver {
else {
try{
String elem = appProfile.get(0);
- DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- Node node = docBuilder.parse(new InputSource(new StringReader(elem))).getDocumentElement();
- XPathHelper helper = new XPathHelper(node);
+ DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ document = docBuilder.parse(new InputSource(new StringReader(elem)));
+ rootElement = document.getDocumentElement();
+ XPathHelper helper = new XPathHelper(rootElement);
List scopes = helper.evaluate(RESOURCE_PROFILE_BODY_END_POINT_SCOPE_TEXT);
for (String scopeFound : scopes) {
List vreName = helper.evaluate("/Resource/Profile/Body/EndPoint[SCOPE='"+scopeFound.toString()+"']/VRE_NAME/text()");
@@ -120,7 +131,31 @@ public class ApplicationProfileReaderForCatalogueResolver {
}
+
/**
+ * Gets the root document.
+ *
+ * @return the rootDocument
+ */
+ public Element getRootDocument() {
+
+ return rootElement;
+ }
+
+
+ /**
+ * Gets the document.
+ *
+ * @return the document
+ */
+ public Document getDocument(){
+ return document;
+ }
+
+
+ /**
+ * Gets the hash vre name scope.
+ *
* @return the hashVreNameScope
*/
public Map getHashVreNameScope() {
@@ -157,6 +192,4 @@ public class ApplicationProfileReaderForCatalogueResolver {
ApplicationProfileReaderForCatalogueResolver reader = new ApplicationProfileReaderForCatalogueResolver(scope, true);
System.out.println(reader);
}*/
-
-
}
diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CkanPorltetApplicationProfile.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanPorltetApplicationProfile.java
similarity index 97%
rename from src/main/java/org/gcube/datatransfer/resolver/catalogue/CkanPorltetApplicationProfile.java
rename to src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanPorltetApplicationProfile.java
index 25d38cb..a9c5eae 100644
--- a/src/main/java/org/gcube/datatransfer/resolver/catalogue/CkanPorltetApplicationProfile.java
+++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/CkanPorltetApplicationProfile.java
@@ -2,7 +2,7 @@
*
*/
-package org.gcube.datatransfer.resolver.catalogue;
+package org.gcube.datatransfer.resolver.catalogue.resource;
import static org.gcube.resources.discovery.icclient.ICFactory.client;
diff --git a/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/UpdateApplicationProfileCatalogueResolver.java b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/UpdateApplicationProfileCatalogueResolver.java
new file mode 100644
index 0000000..017a2cf
--- /dev/null
+++ b/src/main/java/org/gcube/datatransfer/resolver/catalogue/resource/UpdateApplicationProfileCatalogueResolver.java
@@ -0,0 +1,156 @@
+/**
+ *
+ */
+
+package org.gcube.datatransfer.resolver.catalogue.resource;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.List;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.log4j.Logger;
+import org.gcube.common.resources.gcore.GenericResource;
+import org.gcube.common.resources.gcore.Resource;
+import org.gcube.common.resources.gcore.Resources;
+import org.gcube.common.resources.gcore.utils.XPathHelper;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.datatransfer.resolver.applicationprofile.ApplicationProfileNotFoundException;
+import org.gcube.datatransfer.resolver.applicationprofile.ScopeUtil;
+import org.gcube.informationsystem.publisher.RegistryPublisherFactory;
+import org.gcube.informationsystem.publisher.ScopedPublisher;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * The Class UpdateApplicationProfileCatalogueResolver.
+ *
+ * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Feb 28, 2017
+ */
+public class UpdateApplicationProfileCatalogueResolver {
+
+
+ private static Logger logger = Logger.getLogger(UpdateApplicationProfileCatalogueResolver.class);
+ private static boolean useRootScope = false;
+
+
+ /**
+ * Validate end point. If the EndPoint VRE-FULLNAME does not exist it will be added to Application Profile: {@link ApplicationProfileReaderForCatalogueResolver#RESOURCE_NAME}
+ *
+ * @param scopeToInstanceResolver the scope to instance resolver
+ * @param VRE the vre
+ * @param fullScope the full scope
+ * @throws ApplicationProfileNotFoundException the application profile not found exception
+ */
+ public static void validateEndPoint(String scopeToInstanceResolver, String VRE, String fullScope) throws ApplicationProfileNotFoundException {
+ logger.info("Checking if the VRE_NAME: "+VRE+", exists into Application Profile: "+ApplicationProfileReaderForCatalogueResolver.RESOURCE_NAME+" using scope: "+scopeToInstanceResolver);
+ ApplicationProfileReaderForCatalogueResolver appPrCatResolver = new ApplicationProfileReaderForCatalogueResolver(scopeToInstanceResolver, true);
+ Element root = appPrCatResolver.getRootDocument();
+ String originalScope = null;
+ try {
+ XPathHelper helper = new XPathHelper(root);
+ List scopes = helper.evaluate(ApplicationProfileReaderForCatalogueResolver.RESOURCE_PROFILE_BODY_END_POINT_SCOPE_TEXT);
+ for (String scopeFound : scopes) {
+ //List vreName = helper.evaluate("/Resource/Profile/Body/EndPoint[SCOPE='" +scopeFound.toString() + "']/VRE_NAME/text()");
+ if(fullScope.compareTo(scopeFound)==0){
+ logger.info("The full scope: " + fullScope + ", exists into "+ApplicationProfileReaderForCatalogueResolver.RESOURCE_NAME+", skipping update VRE_NAME: "+VRE);
+ return;
+ }
+ }
+
+ logger.info("The full scope: " + fullScope + ", does not exist into "+ApplicationProfileReaderForCatalogueResolver.RESOURCE_NAME+", creating the new end point VRE_NAME: "+VRE+", fullScope: "+fullScope);
+ NodeList body = root.getElementsByTagName(ApplicationProfileReaderForCatalogueResolver.BODY);
+
+ if(body==null || body.getLength()==0)
+ throw new Exception("Body not found");
+
+ Document document = addNewEndPoint(appPrCatResolver.getDocument(), VRE, fullScope);
+
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
+ //initialize StreamResult with File object to save to file
+ StreamResult result = new StreamResult(new StringWriter());
+ DOMSource source2 = new DOMSource(document);
+ transformer.transform(source2, result);
+
+ logger.trace("Updated resource: \n"+result.getWriter().toString());
+
+ originalScope = ScopeProvider.instance.get();
+ String discoveryScope = useRootScope?ScopeUtil.getInfrastructureNameFromScope(scopeToInstanceResolver):scopeToInstanceResolver;
+ ScopeProvider.instance.set(discoveryScope);
+
+ ScopedPublisher rp=RegistryPublisherFactory.scopedPublisher();
+ Resource resource = toResource(result);
+ rp.update(resource);
+ logger.trace("Generic Resource updated on IS successfully");
+ }
+ catch (Exception e) {
+ logger.error("Error ", e);
+ throw new ApplicationProfileNotFoundException("Error during parsing application profile with resource name: " +ApplicationProfileReaderForCatalogueResolver.RESOURCE_NAME + " in the scope: " + scopeToInstanceResolver);
+ }finally{
+ if(originalScope!=null && !originalScope.isEmpty()){
+ ScopeProvider.instance.set(originalScope);
+ logger.info("scope provider setted to orginal scope: "+originalScope);
+ }else{
+ ScopeProvider.instance.reset();
+ logger.info("scope provider reset");
+ }
+ }
+ }
+
+
+ /**
+ * To resource.
+ *
+ * @param result the result
+ * @return the generic resource
+ */
+ private static GenericResource toResource(StreamResult result){
+ InputStream is = new ByteArrayInputStream(result.getWriter().toString().getBytes());
+ return Resources.unmarshal(GenericResource.class, is);
+ }
+
+
+
+ /**
+ * Adds the new end point.
+ *
+ * @param document the document
+ * @param VRE the vre
+ * @param fullScope the full scope
+ * @return the document
+ */
+ private static Document addNewEndPoint(Document document, String VRE, String fullScope){
+ Element newEndPoint = document.createElement(ApplicationProfileReaderForCatalogueResolver.END_POINT);
+ Element newScope = document.createElement(ApplicationProfileReaderForCatalogueResolver.SCOPE);
+ newScope.setTextContent(fullScope);
+ Element newVREName = document.createElement(ApplicationProfileReaderForCatalogueResolver.VRE_NAME);
+ newVREName.setTextContent(VRE);
+
+ newEndPoint.appendChild(newScope);
+ newEndPoint.appendChild(newVREName);
+ document.getElementsByTagName(ApplicationProfileReaderForCatalogueResolver.BODY).item(0).appendChild(newEndPoint);
+
+ return document;
+ }
+
+ public static void main(String[] args) {
+
+ String scope = "/gcube";
+ try {
+ UpdateApplicationProfileCatalogueResolver.validateEndPoint(
+ scope, "gcube", "/gcube/devsec");
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+}
+}