From bffb8f3d98fc8663fe532ea194b65b31c11ce84d Mon Sep 17 00:00:00 2001 From: "francesco.mangiacrapa" Date: Mon, 1 Jun 2020 16:00:23 +0200 Subject: [PATCH] initial commit --- .classpath | 38 + .project | 23 + .settings/org.eclipse.jdt.core.prefs | 15 + .settings/org.eclipse.m2e.core.prefs | 4 + pom.xml | 228 ++++++ .../ckanutillibrary/CkanUtilLibrary.gwt.xml | 8 + .../ckan/ExtendCkanClient.java | 240 ++++++ .../ckanutillibrary/ckan/PatchedCkan.java | 113 +++ .../ckan/SimpleExtendCkanClient.java | 168 +++++ .../ckanutillibrary/db/DBCaller.java | 209 ++++++ .../ckanutillibrary/gcat/GCatCaller.java | 69 ++ .../ApplicationProfileScopePerUrlReader.java | 105 +++ .../ckanutillibrary/server/CKANTokenBean.java | 44 ++ .../ckanutillibrary/server/DataCatalogue.java | 200 +++++ .../server/DataCatalogueFactory.java | 78 ++ .../server/DataCatalogueImpl.java | 543 ++++++++++++++ .../server/DataCatalogueRunningCluster.java | 690 ++++++++++++++++++ .../server/utils/CatalogueUtilMethods.java | 139 ++++ .../utils/SessionCatalogueAttributes.java | 17 + .../server/utils/url/EntityContext.java | 24 + .../shared/CKanUserWrapper.java | 134 ++++ .../shared/CkanDatasetRelationship.java | 96 +++ .../shared/DatasetRelationships.java | 27 + .../ckanutillibrary/shared/LandingPages.java | 57 ++ .../ckanutillibrary/shared/ResourceBean.java | 152 ++++ .../shared/RolesCkanGroupOrOrg.java | 39 + .../ckanutillibrary/shared/State.java | 10 + .../ckanutillibrary/shared/Statistics.java | 54 ++ .../ApplicationProfileNotFoundException.java | 12 + .../NoApplicationProfileMasterException.java | 20 + ...DataCatalogueRuntimeResourceException.java | 21 + .../shared/ex/ServiceEndPointException.java | 19 + .../ex/TooManyRunningClustersException.java | 22 + target/classes/META-INF/MANIFEST.MF | 15 + .../catalogue-util-library/pom.properties | 7 + .../catalogue-util-library/pom.xml | 228 ++++++ .../ckanutillibrary/CkanUtilLibrary.gwt.xml | 8 + .../ckan/ExtendCkanClient.class | Bin 0 -> 8469 bytes .../ckan/ExtendCkanClient.java | 240 ++++++ .../ckan/PatchedCkan$GroupResponse.class | Bin 0 -> 588 bytes .../PatchedCkan$OrganizationResponse.class | Bin 0 -> 612 bytes .../ckanutillibrary/ckan/PatchedCkan.class | Bin 0 -> 927 bytes .../ckanutillibrary/ckan/PatchedCkan.java | 113 +++ .../ckan/SimpleExtendCkanClient.class | Bin 0 -> 7454 bytes .../ckan/SimpleExtendCkanClient.java | 168 +++++ .../ckanutillibrary/db/DBCaller.class | Bin 0 -> 6228 bytes .../ckanutillibrary/db/DBCaller.java | 209 ++++++ .../ckanutillibrary/gcat/GCatCaller.class | Bin 0 -> 2096 bytes .../ckanutillibrary/gcat/GCatCaller.java | 69 ++ .../ApplicationProfileScopePerUrlReader.class | Bin 0 -> 5309 bytes .../ApplicationProfileScopePerUrlReader.java | 105 +++ .../server/CKANTokenBean.class | Bin 0 -> 895 bytes .../ckanutillibrary/server/CKANTokenBean.java | 44 ++ .../server/DataCatalogue.class | Bin 0 -> 2450 bytes .../ckanutillibrary/server/DataCatalogue.java | 200 +++++ .../DataCatalogueFactory$CacheBean.class | Bin 0 -> 927 bytes .../server/DataCatalogueFactory.class | Bin 0 -> 3023 bytes .../server/DataCatalogueFactory.java | 78 ++ .../server/DataCatalogueImpl.class | Bin 0 -> 20700 bytes .../server/DataCatalogueImpl.java | 543 ++++++++++++++ ...er$ACCESS_LEVEL_TO_CATALOGUE_PORTLET.class | Bin 0 -> 1718 bytes .../server/DataCatalogueRunningCluster.class | Bin 0 -> 18230 bytes .../server/DataCatalogueRunningCluster.java | 690 ++++++++++++++++++ .../server/utils/CatalogueUtilMethods.class | Bin 0 -> 3812 bytes .../server/utils/CatalogueUtilMethods.java | 139 ++++ .../utils/SessionCatalogueAttributes.class | Bin 0 -> 855 bytes .../utils/SessionCatalogueAttributes.java | 17 + .../server/utils/url/EntityContext.class | Bin 0 -> 1600 bytes .../server/utils/url/EntityContext.java | 24 + .../shared/CKanUserWrapper.class | Bin 0 -> 3296 bytes .../shared/CKanUserWrapper.java | 134 ++++ .../shared/CkanDatasetRelationship.class | Bin 0 -> 2209 bytes .../shared/CkanDatasetRelationship.java | 96 +++ .../shared/DatasetRelationships.class | Bin 0 -> 1620 bytes .../shared/DatasetRelationships.java | 27 + .../ckanutillibrary/shared/LandingPages.class | Bin 0 -> 1674 bytes .../ckanutillibrary/shared/LandingPages.java | 57 ++ .../ckanutillibrary/shared/ResourceBean.class | Bin 0 -> 2585 bytes .../ckanutillibrary/shared/ResourceBean.java | 152 ++++ .../shared/RolesCkanGroupOrOrg.class | Bin 0 -> 2154 bytes .../shared/RolesCkanGroupOrOrg.java | 39 + .../ckanutillibrary/shared/State.class | Bin 0 -> 1152 bytes .../ckanutillibrary/shared/State.java | 10 + .../ckanutillibrary/shared/Statistics.class | Bin 0 -> 1695 bytes .../ckanutillibrary/shared/Statistics.java | 54 ++ .../ApplicationProfileNotFoundException.class | Bin 0 -> 497 bytes .../ApplicationProfileNotFoundException.java | 12 + .../NoApplicationProfileMasterException.class | Bin 0 -> 767 bytes .../NoApplicationProfileMasterException.java | 20 + ...ataCatalogueRuntimeResourceException.class | Bin 0 -> 728 bytes ...DataCatalogueRuntimeResourceException.java | 21 + .../shared/ex/ServiceEndPointException.class | Bin 0 -> 700 bytes .../shared/ex/ServiceEndPointException.java | 19 + .../ex/TooManyRunningClustersException.class | Bin 0 -> 716 bytes .../ex/TooManyRunningClustersException.java | 22 + 95 files changed, 7178 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 pom.xml create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/State.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java create mode 100644 src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.java create mode 100644 target/classes/META-INF/MANIFEST.MF create mode 100644 target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.properties create mode 100644 target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.xml create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan$GroupResponse.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan$OrganizationResponse.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory$CacheBean.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster$ACCESS_LEVEL_TO_CATALOGUE_PORTLET.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.class create mode 100644 target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..ae19729 --- /dev/null +++ b/.classpath @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..93a6d99 --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + catalogue-util-library + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..b9a1035 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,15 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..668791f --- /dev/null +++ b/pom.xml @@ -0,0 +1,228 @@ + + 4.0.0 + + + maven-parent + org.gcube.tools + 1.1.0 + + + + org.gcube.datacatalogue + catalogue-util-library + 0.1.0-SNAPSHOT + + CKan utility library + + Utility library to retrieve users information, organizations information and so on from the ckan d4science datacatalogue + + + + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + https://code-repo.d4science.org/gCubeSystem/${project.artifactId} + + + + data-catalogue + 0.4.2 + 9.4.1208.jre7 + UTF-8 + UTF-8 + 2.7.0 + + + + + + org.gcube.distribution + maven-portal-bom + LATEST + pom + import + + + + + + + com.google.gwt + gwt-user + provided + + + + + eu.trentorise.opendata + jackan + ${jackanVersion} + compile + + + + org.gcube.data-publishing + gcat-client + [1.0.0, 2.0.0-SNAPSHOT) + compile + + + + + + + + + + + junit + junit + 4.8 + test + + + org.gcube.common.portal + portal-manager + provided + + + org.gcube.resources.discovery + ic-client + provided + + + org.gcube.core + common-scope-maps + provided + + + + org.gcube.core + common-encryption + provided + + + org.gcube.dvos + usermanagement-core + provided + + + net.htmlparser.jericho + jericho-html + 3.3 + compile + + + com.google.guava + guava + + + com.googlecode.json-simple + json-simple + compile + + + org.apache.solr + solr-solrj + [4.10.2,5.0.0) + + + org.slf4j + slf4j-log4j12 + provided + + + org.slf4j + slf4j-api + provided + + + + + + + src/main/java + + **/*.* + + + + + + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + true + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + ${distroDirectory}/descriptor.xml + + + + fully.qualified.MainClass + + + + + + servicearchive + install + + single + + + + + + + diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml new file mode 100644 index 0000000..a3990ca --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java new file mode 100644 index 0000000..43a2fce --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java @@ -0,0 +1,240 @@ +/** + * + */ +package org.gcube.datacatalogue.ckanutillibrary.ckan; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URLEncoder; +import java.util.Arrays; + +import javax.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; + +import eu.trentorise.opendata.jackan.CheckedCkanClient; +import eu.trentorise.opendata.jackan.exceptions.CkanException; +import eu.trentorise.opendata.jackan.exceptions.JackanException; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Request; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Response; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanOrganization; +import eu.trentorise.opendata.jackan.model.CkanResponse; + + +/** + * The Class ExtendCkanClient. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Jun 14, 2019 + */ +public class ExtendCkanClient extends CheckedCkanClient implements PatchedCkan{ + + private static final Logger logger = LoggerFactory.getLogger(ExtendCkanClient.class); + + @Nullable + private static ObjectMapper objectMapper; + + private String catalogueURL; + private String ckanToken; + private int extendTimeout = 120000; //in milliseconds + + + /** + * Instantiates a new extend ckan client. + * + * @param catalogueURL the catalogue url + */ + public ExtendCkanClient(String catalogueURL) { + super(catalogueURL); + this.catalogueURL = catalogueURL; + + } + + /** + * Instantiates a new extend ckan client. + * + * @param catalogueURL the catalogue url + * @param ckanToken the ckan token + */ + public ExtendCkanClient(String catalogueURL, @Nullable String ckanToken) { + super(catalogueURL, ckanToken); + this.catalogueURL = catalogueURL; + this.ckanToken = ckanToken; + } + + /** + * Instantiates a new extend ckan client. + * + * @param catalogueURL the catalogue url + * @param ckanToken the ckan token + * @param timeout the timeout + */ + public ExtendCkanClient(String catalogueURL, @Nullable String ckanToken, int timeout) { + super(catalogueURL, ckanToken); + this.catalogueURL = catalogueURL; + this.ckanToken = ckanToken; + this.extendTimeout = timeout; + } + + + /** + * Configures the request. Should work both for GETs and POSTs. + * + * @param request the request + * @return the request + */ + @Override + protected Request configureRequest(Request request) { + request = super.configureRequest(request); + + logger.debug("Setting timeout to {}", extendTimeout); + + request.socketTimeout(this.extendTimeout) + .connectTimeout(this.extendTimeout); + + return request; + } + + /** + * Gets the catalogue url. + * + * @return the catalogueURL + */ + public String getCatalogueURL() { + + return catalogueURL; + } + + + /** + * Gets the ckan token. + * + * @return the ckanToken + */ + @Override + public String getCkanToken() { + + return ckanToken; + } + + /** + * Gets the timeout. + * + * @return the timeout + */ + public int getTimeout() { + return extendTimeout; + } + + /* (non-Javadoc) + * @see eu.trentorise.opendata.jackan.CkanClient#getOrganization(java.lang.String) + */ + public synchronized CkanOrganization getOrganization(String idOrName) { + checkNotNull(idOrName, "Need a valid id or name!"); + logger.info("Patched read organization for id/name: {}", idOrName); + return getHttp(OrganizationResponse.class, "/api/3/action/organization_show", "id", idOrName, + "include_datasets", "false", "include_users", "true").result; + + } + + + /* (non-Javadoc) + * @see eu.trentorise.opendata.jackan.CkanClient#getGroup(java.lang.String) + */ + public synchronized CkanGroup getGroup(String idOrName) { + checkNotNull(idOrName, "Need a valid id or name!"); + logger.info("Patched read group for id/name: {}", idOrName); + return getHttp(GroupResponse.class, "/api/3/action/group_show", "id", idOrName, "include_datasets", + "false", "include_users", "true").result; + } + + + /** + * Retrieves the Jackson object mapper for reading operations. Internally, + * Object mapper is initialized at first call. + * + * @return the object mapper + */ + static ObjectMapper getObjectMapper() { + if (objectMapper == null) { + objectMapper = new ObjectMapper(); + configureObjectMapper(objectMapper); + } + return objectMapper; + } + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#getHttp(java.lang.Class, java.lang.String, java.lang.Object[]) + */ + public T getHttp(Class responseType, String path, Object... params) { + + checkNotNull(responseType); + checkNotNull(path); + String fullUrl = calcFullUrl(path, params); + T ckanResponse; + String returnedText; + + try { + + logger.debug("getting {}", fullUrl); + Request request = Request.Get(fullUrl); + configureRequest(request); + Response response = request.execute(); + InputStream stream = response.returnResponse() + .getEntity() + .getContent(); + + try (InputStreamReader reader = new InputStreamReader(stream, Charsets.UTF_8)) { + returnedText = CharStreams.toString(reader); + } + + logger.trace("returnedText {}", returnedText); + } catch (Exception ex) { + throw new CkanException("Error while performing GET. Request url was: " + fullUrl, this, ex); + } + try { + ckanResponse = getObjectMapper().readValue(returnedText, responseType); + } catch (Exception ex) { + throw new CkanException( + "Couldn't interpret json returned by the server! Returned text was: " + returnedText, this, ex); + } + + if (!ckanResponse.isSuccess()) { + throwCkanException("Error while performing GET. Request url was: " + fullUrl, ckanResponse); + } + return ckanResponse; + } + + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#calcFullUrl(java.lang.String, java.lang.Object[]) + */ + public String calcFullUrl(String path, Object[] params) { + checkNotNull(path); + + try { + StringBuilder sb = new StringBuilder().append(catalogueURL) + .append(path); + for (int i = 0; i < params.length; i += 2) { + sb.append(i == 0 ? "?" : "&") + .append(URLEncoder.encode(params[i].toString(), "UTF-8")) + .append("=") + .append(URLEncoder.encode(params[i + 1].toString(), "UTF-8")); + } + return sb.toString(); + } catch (Exception ex) { + throw new JackanException("Error while building url to perform GET! \n path: " + path + " \n params: " + + Arrays.toString(params), ex); + } + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan.java new file mode 100644 index 0000000..b7501fd --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan.java @@ -0,0 +1,113 @@ +package org.gcube.datacatalogue.ckanutillibrary.ckan; + +import eu.trentorise.opendata.jackan.CkanClient; +import eu.trentorise.opendata.jackan.exceptions.CkanException; +import eu.trentorise.opendata.jackan.exceptions.JackanException; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanOrganization; +import eu.trentorise.opendata.jackan.model.CkanResponse; + +/** + * The Interface PatchedCkan. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Jun 14, 2019 + */ +public interface PatchedCkan { + + /** + * + * This Class is private in {@link CkanClient} so I need to rewrite it + * + * The Class OrganizationResponse. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Jun 7, 2019 + */ + static class OrganizationResponse extends CkanResponse { + + public CkanOrganization result; + + } + + /** + * + * + * This Class is private in {@link CkanClient} so I need to rewrite it + * + * + * The Class GroupResponse. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Jun 7, 2019 + */ + static class GroupResponse extends CkanResponse { + + public CkanGroup result; + + /** + * Instantiates a new group response. + */ + public GroupResponse() { + + } + } + + /** + * + * This method is private in {@link CkanClient} so I need to rewrite it + * + * + * + * Performs HTTP GET on server. If {@link CkanResponse#isSuccess()} is false + * throws {@link CkanException}. + * + * @param the generic type + * @param responseType a descendant of CkanResponse + * @param path something like /api/3/package_show + * @param params list of key, value parameters. They must be not be url + * encoded. i.e. "id","laghi-monitorati-trento" + * @return the http + * @throws CkanException on error + */ + public T getHttp(Class responseType, String path, Object... params); + + /** + * + * This method is private in {@link CkanClient} so I need to rewrite it + * + * + * Calculates a full url out of the provided params. + * + * @param path something like /api/3/package_show + * @param params list of key, value parameters. They must be not be url encoded. + * i.e. "id","laghi-monitorati-trento" + * @return the full url to be called. + * @throws JackanException if there is any error building the url + */ + public String calcFullUrl(String path, Object[] params); + + + + // WE NEED TO OVERRIDE THE FOLLOWING METHODS + + /** + * Gets the organization. + * + * @param idOrName the id or name + * @return the organization + */ + public CkanOrganization getOrganization(String idOrName); + + /** + * Gets the group. + * + * @param idOrName the id or name + * @return the group + */ + public CkanGroup getGroup(String idOrName); + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.java new file mode 100644 index 0000000..93c59cd --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.java @@ -0,0 +1,168 @@ +package org.gcube.datacatalogue.ckanutillibrary.ckan; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URLEncoder; +import java.util.Arrays; + +import javax.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; + +import eu.trentorise.opendata.jackan.CkanClient; +import eu.trentorise.opendata.jackan.exceptions.CkanException; +import eu.trentorise.opendata.jackan.exceptions.JackanException; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Request; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Response; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanOrganization; +import eu.trentorise.opendata.jackan.model.CkanResponse; + + +/** + * The Class SimpleExtendCkanClient. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Jun 7, 2019 + */ +public class SimpleExtendCkanClient extends CkanClient implements PatchedCkan{ + + + private String catalogueURL; + + @Nullable + private static ObjectMapper objectMapper; + + private static final Logger logger = LoggerFactory.getLogger(SimpleExtendCkanClient.class); + + /** + * Instantiates a new simple extend ckan client. + * + * @param catalogueURL the catalogue URL + */ + public SimpleExtendCkanClient(String catalogueURL) { + super(catalogueURL); + this.catalogueURL = catalogueURL; + } + + /* (non-Javadoc) + * @see eu.trentorise.opendata.jackan.CkanClient#getOrganization(java.lang.String) + */ + public synchronized CkanOrganization getOrganization(String idOrName) { + checkNotNull(idOrName, "Need a valid id or name!"); + logger.info("Patched read organization for id/name: {}", idOrName); + return getHttp(OrganizationResponse.class, "/api/3/action/organization_show", "id", idOrName, + "include_datasets", "false", "include_users", "true").result; + + } + + + /* (non-Javadoc) + * @see eu.trentorise.opendata.jackan.CkanClient#getGroup(java.lang.String) + */ + public synchronized CkanGroup getGroup(String idOrName) { + checkNotNull(idOrName, "Need a valid id or name!"); + logger.info("Patched read group for id/name: {}", idOrName); + return getHttp(GroupResponse.class, "/api/3/action/group_show", "id", idOrName, "include_datasets", + "false", "include_users", "true").result; + } + + + /** + * Retrieves the Jackson object mapper for reading operations. Internally, + * Object mapper is initialized at first call. + * + * @return the object mapper + */ + public static ObjectMapper getObjectMapper() { + if (objectMapper == null) { + objectMapper = new ObjectMapper(); + configureObjectMapper(objectMapper); + } + return objectMapper; + } + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#getHttp(java.lang.Class, java.lang.String, java.lang.Object[]) + */ + public T getHttp(Class responseType, String path, Object... params) { + + checkNotNull(responseType); + checkNotNull(path); + String fullUrl = calcFullUrl(path, params); + T ckanResponse; + String returnedText; + + try { + + logger.debug("getting {}", fullUrl); + Request request = Request.Get(fullUrl); + configureRequest(request); + Response response = request.execute(); + InputStream stream = response.returnResponse() + .getEntity() + .getContent(); + + try (InputStreamReader reader = new InputStreamReader(stream, Charsets.UTF_8)) { + returnedText = CharStreams.toString(reader); + } + + logger.trace("returnedText {}", returnedText); + } catch (Exception ex) { + throw new CkanException("Error while performing GET. Request url was: " + fullUrl, this, ex); + } + try { + ckanResponse = getObjectMapper().readValue(returnedText, responseType); + } catch (Exception ex) { + throw new CkanException( + "Couldn't interpret json returned by the server! Returned text was: " + returnedText, this, ex); + } + + if (!ckanResponse.isSuccess()) { + throwCkanException("Error while performing GET. Request url was: " + fullUrl, ckanResponse); + } + return ckanResponse; + } + + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#calcFullUrl(java.lang.String, java.lang.Object[]) + */ + public String calcFullUrl(String path, Object[] params) { + checkNotNull(path); + + try { + StringBuilder sb = new StringBuilder().append(catalogueURL) + .append(path); + for (int i = 0; i < params.length; i += 2) { + sb.append(i == 0 ? "?" : "&") + .append(URLEncoder.encode(params[i].toString(), "UTF-8")) + .append("=") + .append(URLEncoder.encode(params[i + 1].toString(), "UTF-8")); + } + return sb.toString(); + } catch (Exception ex) { + throw new JackanException("Error while building url to perform GET! \n path: " + path + " \n params: " + + Arrays.toString(params), ex); + } + } + + /** + * Gets the catalogue url. + * + * @return the catalogueURL + */ + public String getCatalogueURL() { + + return catalogueURL; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java new file mode 100644 index 0000000..7be49c9 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java @@ -0,0 +1,209 @@ +package org.gcube.datacatalogue.ckanutillibrary.db; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DBCaller { + + private static final Logger LOG = LoggerFactory.getLogger(DBCaller.class); + + private String CKAN_DB_URL; + private Integer CKAN_DB_PORT; + private String CKAN_DB_NAME; + private String CKAN_DB_USER; + private String CKAN_DB_PASSWORD; + + public DBCaller() { + } + + public DBCaller(String cKAN_DB_URL, Integer cKAN_DB_PORT, String cKAN_DB_NAME, String cKAN_DB_USER, + String cKAN_DB_PASSWORD) { + CKAN_DB_URL = cKAN_DB_URL; + CKAN_DB_PORT = cKAN_DB_PORT; + CKAN_DB_NAME = cKAN_DB_NAME; + CKAN_DB_USER = cKAN_DB_USER; + CKAN_DB_PASSWORD = cKAN_DB_PASSWORD; + } + + + /** + * Retrieve connection from the pool + * @return a connection available within the pool + * @throws SQLException + * @throws ClassNotFoundException + */ + private Connection getConnection() throws SQLException, ClassNotFoundException{ + + LOG.debug("CONNECTION REQUEST"); + // create db connection + Class.forName("org.postgresql.Driver"); + + String dbBaseConnectionURL = String.format("jdbc:postgresql://%s", CKAN_DB_URL); + + if(CKAN_DB_PORT!=null) + dbBaseConnectionURL+=":" + CKAN_DB_PORT; + + dbBaseConnectionURL+="/" + CKAN_DB_NAME; + + Connection connection = DriverManager.getConnection(dbBaseConnectionURL, CKAN_DB_USER, CKAN_DB_PASSWORD); + +// Connection connection = DriverManager.getConnection( +// "jdbc:postgresql://" + CKAN_DB_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD); + return connection; + + } + + /** + * Retrieve the map (groups id, capacity) with the groups to which the user belongs by querying directly the database. + * @param username + * @return + * @throws SQLException + * @throws ClassNotFoundException + */ + public Map getGroupsByUserFromDB(String userId){ + checkNotNull(userId); + + //couples (groups id, capacity) of the user in the group + + Map toReturn = new HashMap(); + Connection connection = null; + try{ + + connection = getConnection(); + ResultSet rs; + + String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" " + + "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?" + + " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;"; + + + PreparedStatement preparedStatement = connection.prepareStatement(joinQuery); + preparedStatement.setString(1, userId); + preparedStatement.setBoolean(2, false); + rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity"))); + } + + }catch(Exception e){ + LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage()); + return null; + }finally{ + closeConnection(connection); + } + return toReturn; + } + + /** + * Retrieve the map (organisation id, capacity) with the organisations to which the user belongs by querying directly the database. + * @param username + * @return + * @throws SQLException + * @throws ClassNotFoundException + */ + public Map getOrganizationsByUserFromDB(String userId){ + checkNotNull(userId); + + Map toReturn = new HashMap(); + Connection connection = null; + try{ + + connection = getConnection(); + ResultSet rs; + + String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" " + + "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?" + + " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;"; + + + PreparedStatement preparedStatement = connection.prepareStatement(joinQuery); + preparedStatement.setString(1, userId); + preparedStatement.setBoolean(2, true); + rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity"))); + } + + }catch(Exception e){ + LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage()); + return null; + }finally{ + closeConnection(connection); + } + return toReturn; + } + + + public String getApiKeyFromUsername(String username, String state) { + + LOG.debug("Request api key for user = " + username); + + // checks + checkNotNull(username); + checkArgument(!username.isEmpty()); + + // the connection + Connection connection = null; + String apiToReturn = null; + + try{ + + connection = getConnection(); + + String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;"; + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setString(1, username); + preparedStatement.setString(2, state); + + ResultSet rs = preparedStatement.executeQuery(); + while (rs.next()) { + apiToReturn = rs.getString("apikey"); + LOG.debug("Api key "+apiToReturn.substring(0,10)+" MASKED-TOKEN retrieved for user " + username); + break; + } + + return apiToReturn; + + }catch(Exception e){ + LOG.error("Unable to retrieve key for user " + username, e); + }finally{ + closeConnection(connection); + } + + return null; + } + + + /** + * Tries to close a connection + * @param connection + */ + private void closeConnection(Connection connection){ + + if(connection != null){ + try{ + connection.close(); + }catch(Exception e){ + LOG.error("Unable to close this connection ", e); + } + } + + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java new file mode 100644 index 0000000..c14eca7 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java @@ -0,0 +1,69 @@ +package org.gcube.datacatalogue.ckanutillibrary.gcat; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.List; + +import org.gcube.datacatalogue.ckanutillibrary.ckan.SimpleExtendCkanClient; +import org.gcube.gcat.client.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import eu.trentorise.opendata.jackan.model.CkanDataset; +import eu.trentorise.opendata.jackan.model.CkanLicense; + +// TODO: Auto-generated Javadoc +/** + * The Class GCatCaller. + * + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) + * May 29, 2020 + */ +public class GCatCaller { + + private SimpleExtendCkanClient jackanCkanClient; + + private String catalogueURL; + + private static final Logger LOG = LoggerFactory.getLogger(GCatCaller.class); + + /** + * Instantiates a new g cat caller. + */ + public GCatCaller(String catalogueURL) { + this.catalogueURL = catalogueURL; + this.jackanCkanClient = new SimpleExtendCkanClient(catalogueURL); + } + + + /** + * Gets the dataset for name. + * + * @param datasetIdOrName the dataset id or name + * @return the dataset for name + * @throws JsonParseException the json parse exception + * @throws JsonMappingException the json mapping exception + * @throws IOException Signals that an I/O exception has occurred. + */ + public CkanDataset getDatasetForName(String datasetIdOrName) throws JsonParseException, JsonMappingException, IOException { + LOG.debug("Get dataset for name "+datasetIdOrName+ "called"); + String json = new Item().read(datasetIdOrName); + return SimpleExtendCkanClient.getObjectMapper().readValue(json, CkanDataset.class); + } + + + /** + * TODO gCAT missing + * @return + * @throws MalformedURLException + */ + + public List getLicenseList() { + LOG.debug("Get linces list called"); + return jackanCkanClient.getLicenseList(); + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.java new file mode 100644 index 0000000..e0d621e --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.java @@ -0,0 +1,105 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import static org.gcube.resources.discovery.icclient.ICFactory.client; + +import java.io.StringReader; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.gcube.common.portal.PortalContext; +import org.gcube.common.resources.gcore.utils.XPathHelper; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +/** + * This class has a method that tries to read the application profile whose structure contains + * couples Scope/Current_Url to check where the the needed information needs to be discovered according to the current + * portlet url. It means that the scope in which the ckan related information will be discovered could be different wrt the running one. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ApplicationProfileScopePerUrlReader { + + private static final Logger logger = LoggerFactory.getLogger(ApplicationProfileScopePerUrlReader.class); + private final static String APPLICATION_PROFILE_NAME = "DataCatalogueMapScopesUrls"; + private final static String QUERY = "for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + + " eq '" + APPLICATION_PROFILE_NAME + "'" + + "return $profile"; + + /** + * Get the scope in which discover for this url. If the Application Profile doesn't contain it, the current scope (taken + * from ScopeProvider is returned). + * @param url + * @return the scope to be used for the given url + */ + public static String getScopePerUrl(String url){ + + logger.info("Request scope for ckan portlet at url " + url); + + String scope = ScopeProvider.instance.get(); + String scopeToReturn = scope; + String rootScopeForInfrastructure = "/" + PortalContext.getConfiguration().getInfrastructureName(); + + if(url == null || url.isEmpty()){ + + logger.info("The url passed is null or empty! Returning current scope [" + scope + "]"); + return scope; + + } + + // set this scope + ScopeProvider.instance.set(rootScopeForInfrastructure); + + logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " + APPLICATION_PROFILE_NAME + " scope: " + rootScopeForInfrastructure); + + try { + Query q = new QueryBox(QUERY); + + DiscoveryClient client = client(); + List appProfile = client.submit(q); + + if (appProfile == null || appProfile.size() == 0) + throw new ApplicationProfileNotFoundException("Your applicationProfile is not registered in the infrastructure"); + else{ + 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); + + List urls = helper.evaluate("/Resource/Profile/Body/EndPoint/URL/text()"); + if (urls != null && urls.size() > 0) { + boolean foundScope = false; + for (int i = 0; i < urls.size(); i++) { + if (urls.get(i).trim().compareTo(url) == 0) { // url found + scopeToReturn = helper.evaluate("/Resource/Profile/Body/EndPoint/Scope/text()").get(i); + logger.debug("Found, returning " + scopeToReturn); + foundScope = true; + break; + } + } + if (!foundScope || scopeToReturn == null || scopeToReturn.isEmpty()){ + logger.debug("Scope is missing for url " + url + ". Returning " + scope); + } + } + else + throw + new ApplicationProfileNotFoundException("Your applicationProfile EndPoint was not found in the profile, consider adding element in "); + } + } catch (Exception e) { + logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e); + }finally{ + ScopeProvider.instance.set(scope); + } + + return scopeToReturn; + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java new file mode 100644 index 0000000..9cd9ba5 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java @@ -0,0 +1,44 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + + +// TODO: Auto-generated Javadoc +/** + * The Class CKANTokenBean. + * + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) + * Jun 1, 2020 + */ +public class CKANTokenBean { + + protected String apiKey; + protected long timestamp; + + /** + * Instantiates a new CKAN token bean. + * + * @param apiKey the api key + * @param timestamp the timestamp + */ + public CKANTokenBean(String apiKey, long timestamp) { + super(); + this.apiKey = apiKey; + this.timestamp = timestamp; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java new file mode 100644 index 0000000..800a459 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java @@ -0,0 +1,200 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import java.util.List; +import java.util.Map; + +import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; + +import eu.trentorise.opendata.jackan.model.CkanDataset; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanLicense; +import eu.trentorise.opendata.jackan.model.CkanOrganization; + +public interface DataCatalogue { + + /** + * Finds the id associated to the chosen license + * + * @param chosenLicense + * @return the id on success, null otherwise + */ + String findLicenseIdByLicenseTitle(String chosenLicense); + + /** + * Given the id or the name of the dataset it returns its current url by + * contacting the uri resolver. If no uri resolver is available, an url that is + * not guaranteed to be long term valid will be generated. Information are not + * encrypted. + * + * @param datasetId + * @return The url of the dataset on success, null otherwise + */ + String getUnencryptedUrlFromDatasetIdOrName(String datasetIdOrName); + + /** + * Create a dataset with those information. The method allows to have multiple + * values for the same custom field key. NOTE: unfortunately java doesn't + * support overload in java interface methods (that's way I cannot use the same + * name for the method) + * + * @param title + * @param name (unique identifier) + * @param organizationNameOrId + * @param author + * @param authorMail + * @param maintainer + * @param maintainerMail + * @param version + * @param description + * @param licenseId + * @param tags + * @param customFields + * @param resources + * @param setPublic (manage visibility: Admin role is needed) + * @return the id of the dataset on success, null otherwise + * @throws Exception + */ + String createCKanDatasetMultipleCustomFields(String title, String name, String organizationNameOrId, String author, + String authorMail, String maintainer, String maintainerMail, long version, String description, + String licenseId, List tags, Map> customFields, List resources, + boolean setPublic) throws Exception; + + /** + * Patch a product with product id productId by using the couples in + * customFieldsToChange. NOTE: only the specified custom fields will be changed. + * If a custom field with a given key already exists, and removeOld is set to + * false, the new values are added at the end of the list. Otherwise they are + * lost. + * + * @param productId + * @param customFieldsToChange + * @param removeOld + * @return + */ + boolean patchProductCustomFields(String productId, Map> customFieldsToChange, + boolean removeOld); + + /** + * Add a resource described by the bean to the dataset id into + * resource.datasetId + * + * @param resource + * @return String the id of the resource on success, null otherwise + */ + String addResourceToDataset(ResourceBean resource) throws Exception; + + /** + * Remove the resource with id resourceId from the dataset in which it is. + * + * @param resourceId + * @return true on success, false otherwise. + */ + boolean deleteResourceFromDataset(String resourceId); + + /** + * Create a dataset with those information. + * + * @param apiKey + * @param title + * @param name (unique identifier) + * @param organizationNameOrId + * @param author + * @param authorMail + * @param maintainer + * @param maintainerMail + * @param version + * @param description + * @param licenseId + * @param tags + * @param customFields + * @param resources + * @param setPublic (manage visibility: Admin role is needed) + * @return the id of the dataset on success, null otherwise + * @throws Exception + */ + + /** + * Checks if a product with such name already exists. Please remember that the + * name is unique. + * + * @param nameOrId the name or the id of the dataset to check + * @return + */ + boolean existProductWithNameOrId(String nameOrId); + + /** + * The method returns the role the user has in the groups he/she belongs to (it + * uses the db, so it is much faster) + * + * @param username + * @param apiKey + * @return + */ + Map> getUserRoleByGroup(String username, String apiKey); + + /** + * Get the list of licenses' titles. + * + * @return the list of licenses' titles + */ + List getLicenseTitles(); + + /** + * Retrieve ckan licenses + * + * @return + */ + List getLicenses(); + + /** + * Retrieve the url of the uri resolver for this catalogue instance/scope + * + * @return + */ + String getUriResolverUrl(); + + /** + * Return the manage product property + * + * @return the manage product property + */ + boolean isManageProductEnabled(); + + /** + * Return the catalogue portlet for this context(i.e. scope) + * + * @return + */ + String getPortletUrl(); + + /** + * Return the ckan catalogue url in this scope. + * + * @return the catalogue url + */ + String getCatalogueUrl(); + + + /** + * Returns the list of organizations to whom the user belongs (with any role) + * @param username + * @return a list of organizations + */ + List getOrganizationsByUser(String username); + + /** + * Returns the list of groups to whom the user belongs (with any role) + * @param username + * @return a list of groups + */ + List getGroupsByUser(String username); + + /** + * Retrieve a ckan dataset given its id + * @param datasetId + * @return + */ + CkanDataset getDataset(String datasetId, String apiKey); + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory.java new file mode 100644 index 0000000..542d882 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory.java @@ -0,0 +1,78 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Please invoke this method to retrieve an object of this kind per scope. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class DataCatalogueFactory { + + private static final Logger logger = LoggerFactory.getLogger(DataCatalogueFactory.class); + private static final long MAX_LIFETIME = 1000 * 60 * 30; // 30 MINUTES + private static DataCatalogueFactory instance = new DataCatalogueFactory(); + private static ConcurrentHashMap cache; + + private class CacheBean{ + DataCatalogueImpl utils; + long ttl; + + public CacheBean(long ttl, DataCatalogueImpl utils){ + this.ttl = ttl; + this.utils = utils; + } + } + + /** + * Private constructor + */ + private DataCatalogueFactory(){ + + logger.debug("Ckan factory object build"); + cache = new ConcurrentHashMap(); + + } + + /** + * Get the factory instance + * @return + */ + public static DataCatalogueFactory getFactory(){ + logger.debug("Factory requested"); + return instance; + } + + /** + * Retrieve the ckan utils information for the given scope + * @param scope + * @return + * @throws Exception + */ + public DataCatalogueImpl getUtilsPerScope(String scope) throws Exception{ + + if(scope == null || scope.isEmpty()) + throw new IllegalArgumentException("Invalid scope given!"); + + if(cache.containsKey(scope) && !expired(cache.get(scope))){ + return cache.get(scope).utils; + } + else{ + logger.info("Creating CKAN LIB utils for scope " + scope); + DataCatalogueImpl utils = new DataCatalogueImpl(scope); + cache.put(scope, new CacheBean(System.currentTimeMillis(), utils)); + return utils; + } + } + + /** + * Check if the ckan information must be retrieved again. + * @param cacheBean + * @return + */ + private boolean expired(CacheBean cacheBean) { + return (cacheBean.ttl + MAX_LIFETIME < System.currentTimeMillis()); + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java new file mode 100644 index 0000000..c2f2839 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java @@ -0,0 +1,543 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.gcube.common.scope.impl.ScopeBean.Type; +import org.gcube.datacatalogue.ckanutillibrary.ckan.ExtendCkanClient; +import org.gcube.datacatalogue.ckanutillibrary.ckan.SimpleExtendCkanClient; +import org.gcube.datacatalogue.ckanutillibrary.db.DBCaller; +import org.gcube.datacatalogue.ckanutillibrary.gcat.GCatCaller; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.url.EntityContext; +import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +import org.gcube.datacatalogue.ckanutillibrary.shared.State; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost; +import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.ContentType; +import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity; +import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient; +import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder; +import eu.trentorise.opendata.jackan.internal.org.apache.http.util.EntityUtils; +import eu.trentorise.opendata.jackan.model.CkanDataset; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanLicense; +import eu.trentorise.opendata.jackan.model.CkanOrganization; +import eu.trentorise.opendata.jackan.model.CkanUser; + +public class DataCatalogueImpl implements DataCatalogue { + + private static final Logger LOG = LoggerFactory.getLogger(DataCatalogueImpl.class); + + private String CKAN_CATALOGUE_URL; + private String CKAN_DB_NAME; + private String CKAN_DB_USER; + private String CKAN_DB_PASSWORD; + private String CKAN_DB_URL; + private Integer CKAN_DB_PORT; + private String PORTLET_URL_FOR_SCOPE; + private String SOLR_URL; + private String CKAN_TOKEN_SYS; + private String CKAN_EMAIL; + private String URI_RESOLVER_URL; + private boolean MANAGE_PRODUCT_BUTTON; + private boolean SOCIAL_POST; + private boolean ALERT_USERS_ON_POST_CREATION; + private String CONTEXT; + private Map extendRoleInOrganization; + + public Map mapAccessURLToCatalogue; + + private static final String CATALOGUE_TAB_ENDING_URL = "/catalogue"; + + // gCat client + private GCatCaller gCatCaller; + + // db client + private DBCaller dbCaller; + + // ckan client + private SimpleExtendCkanClient ckanCaller; + + // hashmap for ckan api keys + private ConcurrentHashMap apiKeysMap; + + // apikey bean expires after X minutes in the above map + private static final int EXPIRE_KEY_TIME = 60 * 60 * 1000; + + + /** + * The ckan catalogue url and database will be discovered in this scope + * @param scope + * @throws Exception if unable to find datacatalogue info + */ + public DataCatalogueImpl(String scope) throws Exception{ + + DataCatalogueRunningCluster runningInstance = new DataCatalogueRunningCluster(scope); + + // save information + CKAN_DB_URL = runningInstance.getDatabaseHosts().get(0).trim(); + CKAN_DB_PORT = runningInstance.getDatabasePorts().get(0); + CKAN_DB_NAME = runningInstance.getDataBaseName().trim(); + CKAN_DB_USER = runningInstance.getDataBaseUser().trim(); + CKAN_DB_PASSWORD = runningInstance.getDataBasePassword().trim(); + + //CKAN_TOKEN_SYS = runningInstance.getSysAdminToken().trim(); + CKAN_EMAIL = runningInstance.getEmailCatalogue().trim(); + + CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0).trim(); + PORTLET_URL_FOR_SCOPE = runningInstance.getPortletUrl().trim(); + mapAccessURLToCatalogue = runningInstance.getMapAccessURLToCatalogue(); + MANAGE_PRODUCT_BUTTON = runningInstance.isManageProductEnabled(); + URI_RESOLVER_URL = runningInstance.getUrlResolver(); + SOCIAL_POST = runningInstance.isSocialPostEnabled(); + ALERT_USERS_ON_POST_CREATION = runningInstance.isAlertEnabled(); + SOLR_URL = runningInstance.getUrlSolr(); + + LOG.info("In the scope: "+scope+", I read the catalogue URL: " + CKAN_CATALOGUE_URL); + + // build the clients + gCatCaller = new GCatCaller(CKAN_CATALOGUE_URL); + + dbCaller = new DBCaller(CKAN_DB_URL, CKAN_DB_PORT, CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD); + + ckanCaller = new SimpleExtendCkanClient(CKAN_CATALOGUE_URL); + + // init map + apiKeysMap = new ConcurrentHashMap(); + + // save the context + CONTEXT = scope; + + // extended roles + extendRoleInOrganization = runningInstance.getExtendRoleInOrganization(); + } + + @Override + public String getCatalogueUrl() { + return CKAN_CATALOGUE_URL; + } + + + @Override + public String getPortletUrl() { + + //PATCHED By Francesco + ScopeBean context = new ScopeBean(CONTEXT); + + if(context.is(Type.INFRASTRUCTURE)) { + LOG.info("Working with the {} scope returning the path read from GR 'Ckan-Porltet': {}", Type.INFRASTRUCTURE.toString(), PORTLET_URL_FOR_SCOPE); + return PORTLET_URL_FOR_SCOPE; + } + + String vreNameLower = context.name().toLowerCase(); + //CHECKING IF THE PORTLET URL CONTAINS THE VRE NAME INTO URL + if(PORTLET_URL_FOR_SCOPE.toLowerCase().contains(vreNameLower)){ + //THE PORLTET URL READ FROM GENERIC RESOUCE 'CkanPortlet' SHOULD BE ALREADY VALID, POITING TO CKAN PORTLET + return PORTLET_URL_FOR_SCOPE; + }else{ + //ADDING VRE getApiKeyFromUsernameNAME AND THE SUFFIX 'CATALOGUE_TAB_ENDING_URL' TO URL + String buildedUrl = PORTLET_URL_FOR_SCOPE.endsWith("/") ? PORTLET_URL_FOR_SCOPE : PORTLET_URL_FOR_SCOPE + "/"; + String defaultSuffix = vreNameLower + CATALOGUE_TAB_ENDING_URL; + buildedUrl+= defaultSuffix; + LOG.warn("The Portlet URL read from Generic Resource 'Ckan-Porltet' does not contain the portlet suffix, so I added the default: "+defaultSuffix); + return buildedUrl; + } + } + + + @Override + public String findLicenseIdByLicenseTitle(String chosenLicense) { + LOG.debug("Requested license id"); + + // checks + checkNotNull(chosenLicense); + + //retrieve the list of available licenses + List licenses = ckanCaller.getLicenseList(); + + for (CkanLicense ckanLicense : licenses) { + if(ckanLicense.getTitle().equals(chosenLicense)) + return ckanLicense.getId(); + } + + return null; + } + + @Override + public List getLicenseTitles() { + + LOG.debug("Request for CKAN licenses"); + + // get the url and the api key of the user + List result = new ArrayList(); + + //retrieve the list of available licenses + List licenses = ckanCaller.getLicenseList(); + + for (CkanLicense ckanLicense : licenses) { + + result.add(ckanLicense.getTitle()); + LOG.debug("License is " + ckanLicense.getTitle() + " and id " + ckanLicense.getId()); + + } + + return result; + } + + @Override + public List getLicenses() { + LOG.debug("Request for CKAN licenses (original jackan objects are going to be retrieved)"); + + //retrieve the list of available licenses + return ckanCaller.getLicenseList(); + } + + @Override + public CkanDataset getDataset(String datasetId, String apiKey) { + + LOG.info("Request ckan dataset with id " + datasetId); + + // checks + checkNotNull(datasetId); + checkArgument(!datasetId.isEmpty()); + + try{ + + if(apiKey!=null && !apiKey.isEmpty()) { + LOG.info("API-KEY found. Calling the "+ExtendCkanClient.class.getSimpleName()); + ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, apiKey); + return client.getDataset(datasetId); + } + + String authzToken = SecurityTokenProvider.instance.get(); + if(authzToken!=null && !authzToken.isEmpty()) { + LOG.info("gcube-token found. Calling the gCat client"); + return gCatCaller.getDatasetForName(datasetId); + } + + LOG.info("No api-key or gcube-token found. Calling Ckan Client without API-KEY"); + return ckanCaller.getDataset(datasetId); + + }catch(Exception e){ + LOG.error("Unable to retrieve such dataset, returning null ...", e); + } + + return null; + } + + + @Override + public String getUnencryptedUrlFromDatasetIdOrName(String datasetIdOrName) { + LOG.debug("Request coming for getting dataset url (not encrypted) of dataset with name/id " + datasetIdOrName); + + // checks + checkNotNull(datasetIdOrName); + checkArgument(!datasetIdOrName.isEmpty()); + String url = null; + try{ + + // get the dataset from name + ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS); + CkanDataset dataset = client.getDataset(datasetIdOrName); + String name = dataset.getName(); + + if(dataset != null){ + + if(getUriResolverUrl() != null) + url = getUrlForProduct(CONTEXT, EntityContext.DATASET, name); + + if(url == null || url.isEmpty()) + url = getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + name, "UTF-8"); + + } + }catch(Exception e){ + LOG.error("Error while retrieving dataset with id/name=" + datasetIdOrName, e); + } //requestEntity.put("clear_url", Boolean.toString(unencrypted)); + return url; + } + + public String createCKanDatasetMultipleCustomFields(String title, String name, String organizationNameOrId, + String author, String authorMail, String maintainer, String maintainerMail, long version, + String description, String licenseId, List tags, Map> customFields, + List resources, boolean setPublic) throws Exception { + return null; + } + + @Override + public Map> getUserRoleByGroup( + String username, String apiKey) { + + checkNotNull(username); + checkNotNull(apiKey); + + checkNotNull(username); + checkNotNull(apiKey); + + Map> toReturn = new HashMap>(); + + try{ + + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + Map partialResult = dbCaller.getGroupsByUserFromDB(ckanUsername); + + for (String groupID : partialResult.keySet()) { + + CkanGroup group = ckanCaller.getGroup(groupID); + HashMap subMap = new HashMap(); + subMap.put(group, partialResult.get(groupID)); + toReturn.put(groupID, subMap); + } + + LOG.debug("Returning map " + toReturn); + }catch(Exception e){ + LOG.error("Failed to retrieve roles of user in his/her own groups",e); + } + + return toReturn; + + } + + + /** + * Retrieve an url for the tuple scope, entity, entity name + * @param context + * @param entityContext + * @param entityName + */ + private String getUrlForProduct(String context, EntityContext entityContext, String entityName){ + + String toReturn = null; + + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { + + HttpPost httpPostRequest = new HttpPost(getUriResolverUrl()); + + JSONObject requestEntity = new JSONObject(); + requestEntity.put("gcube_scope", context); + requestEntity.put("entity_context", entityContext.toString()); + requestEntity.put("entity_name", entityName); + + StringEntity params = new StringEntity(requestEntity.toJSONString(), ContentType.APPLICATION_JSON); + httpPostRequest.setEntity(params); + + HttpResponse response = httpClient.execute(httpPostRequest); + + if(response.getStatusLine().getStatusCode() != 200) + throw new Exception("There was an error while creating an url " + response.getStatusLine()); + + toReturn = EntityUtils.toString(response.getEntity()); + LOG.debug("Result is " + toReturn); + + }catch(Exception e){ + LOG.error("Failed to get an url for this product", e); + } + + return toReturn; + } + + + + @Override + public String getUriResolverUrl() { + return URI_RESOLVER_URL; + } + + /** + * Check if the manage product is enabled + * @return + */ + @Override + public boolean isManageProductEnabled() { + return MANAGE_PRODUCT_BUTTON; + } + + @Override + public List getOrganizationsByUser(String username) { + + LOG.debug("Requested organizations for user " + username); + + // checks + checkNotNull(username); + + // in order to avoid errors, the username is always converted + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + + // list to return + List toReturn = new ArrayList(); + + try{ + + // get the list of all organizations + List organizations = ckanCaller.getOrganizationList(); + + // iterate over them + for (CkanOrganization ckanOrganization : organizations) { + + // get the list of users in it (if you try ckanOrganization.getUsers() it returns null.. maybe a bug TODO) + List users = ckanCaller.getOrganization(ckanOrganization.getName()).getUsers(); + + // check if the current user is among them + for (CkanUser ckanUser : users) { + if(ckanUser.getName().equals(ckanUsername)){ + + LOG.debug("User " + ckanUsername + " is into " + ckanOrganization.getName()); + toReturn.add(ckanOrganization); + break; + + } + } + } + }catch(Exception e){ + LOG.error("Unable to get user's organizations", e); + } + return toReturn; + } + + @Override + public List getGroupsByUser(String username) { + LOG.debug("Requested groups for user " + username); + + // checks + checkNotNull(username); + + // in order to avoid errors, the username is always converted + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + + // list to return + List toReturn = new ArrayList(); + + try{ + + // get the list of all organizations + List groups = ckanCaller.getGroupList(); + + // iterate over them + for (CkanGroup ckanGroup : groups) { + + List users = ckanCaller.getGroup(ckanGroup.getName()).getUsers(); + + // check if the current user is among them + for (CkanUser ckanUser : users) { + if(ckanUser.getName().equals(ckanUsername)){ + + LOG.debug("User " + ckanUsername + " is into " + ckanGroup.getName()); + toReturn.add(ckanGroup); + break; + + } + } + } + }catch(Exception e){ + LOG.error("Unable to get user's groups", e); + } + return toReturn; + } + + //@Override + private String getApiKeyFromUsername(String username) { + + LOG.debug("Request api key for user = " + username); + + // checks + checkNotNull(username); + checkArgument(!username.isEmpty()); + + // in order to avoid errors, the username is always converted + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + + // check in the hashmap first + if(apiKeysMap.containsKey(ckanUsername)){ + CKANTokenBean bean = apiKeysMap.get(ckanUsername); + if(bean.timestamp + EXPIRE_KEY_TIME > System.currentTimeMillis()){ // it's still ok + return bean.apiKey; + } + } + + LOG.debug("Api key was not in cache or it expired"); + + try{ + + String apiToReturn = dbCaller.getApiKeyFromUsername(username, State.ACTIVE.name().toLowerCase()); + + // save into the hashmap + if(apiToReturn != null) + apiKeysMap.put(ckanUsername, new CKANTokenBean(apiToReturn, System.currentTimeMillis())); + + return apiToReturn; + + }catch(Exception e){ + LOG.error("Unable to retrieve key for user " + ckanUsername, e); + } + + return null; + } + + + + + + + + + + + + /* + * + * + * + * + * + * + * + * + * + * WRITE OPERATIONS + * + * + * + * + * + * + * + * + * + * + */ + + + public boolean patchProductCustomFields(String productId, Map> customFieldsToChange, + boolean removeOld) { + return false; + } + + public String addResourceToDataset(ResourceBean resource) throws Exception { + return null; + } + + public boolean deleteResourceFromDataset(String resourceId) { + return false; + } + + public boolean existProductWithNameOrId(String nameOrId) { + return false; + } + + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java new file mode 100644 index 0000000..3f153ea --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java @@ -0,0 +1,690 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import static org.gcube.resources.discovery.icclient.ICFactory.client; +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.gcube.common.encryption.StringEncrypter; +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.resources.gcore.utils.XPathHelper; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.NoApplicationProfileMasterException; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.NoDataCatalogueRuntimeResourceException; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ServiceEndPointException; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.Query; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.gcube.resources.discovery.client.queries.impl.QueryBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Retrieve ckan running instance information in the infrastructure (for both its database and data catalogue url). + * + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + * updated by Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + */ +public class DataCatalogueRunningCluster { + + //logger + private static final Logger logger = LoggerFactory.getLogger(DataCatalogueRunningCluster.class); + + // database of the datacatalogue info + private final static String RUNTIME_DB_RESOURCE_NAME = "CKanDatabase"; + private final static String PLATFORM_DB_NAME = "postgres"; + private final static String APPLICATION_PROFILE_NAME = "CkanPortlet"; + + // data catalogue info + private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue"; + private final static String PLATFORM_CATALOGUE_NAME = "Tomcat"; + + // api key property for SYSADMIN + private final static String API_KEY_PROPERTY = "API_KEY"; + + // catalogue email + private final static String CKAN_EMAIL_PROPERTY = "CATALOGUE_EMAIL"; + + // 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 IS_MANAGE_PRODUCT_ENABLED = "IS_MANAGE_PRODUCT_ENABLED"; // true, false.. missing means false as well (for GRSF records) + + 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 SOLR_INDEX_ADDRESS = "SOLR_INDEX_ADDRESS"; + + // url of the http uri for this scope + private final static String URL_RESOLVER = "URL_RESOLVER"; + + // Other generic resource for delegating roles in groups to users + private final static String CATALOGUE_EXTENDING_ROLES = "CatalogueDelegateRoles"; + + // retrieved data + private List datacatalogueUrls = new ArrayList(); + private List hostsDB = new ArrayList(); + private List portsDB = new ArrayList(); + private String nameDB; + private String userDB; + private String passwordDB; + private String portletUrl; + private String urlSolr; + private boolean manageProductEnabled; + private String urlResolver; + private boolean socialPost; + private boolean alertUsers; + private Map extendRoleInOrganization = new HashMap(0); + + // generic role key + public static final String CKAN_GENERIC_ROLE = "*"; + public static final String ROLE_ORGANIZATION_SEPARATOR = "|"; + public static final String TUPLES_SEPARATOR = ","; + + private static final String DEFAULT_CATALOGUE_EMAIL = "catalogue@d4science.org"; + + /** + * The Enum ACCESS_LEVEL_TO_CATALOGUE_PORTLET. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Nov 12, 2019 + */ + //Added by Francesco, see #18039 + public static final String PUBLIC_VRE_CATALOGUE_URL = "public-vre-url"; + public static enum ACCESS_LEVEL_TO_CATALOGUE_PORTLET {PUBLIC_GATEWAY, PUBLIC_VRE, PRIVATE_VRE}; + public Map mapAccessURLToCatalogue; + + // this token is needed in order to assign roles to user + private String sysAdminToken; + + private String catalogueEmail; + + /** + * Instantiates a new data catalogue running cluster. + * + * @param scope the scope + * @throws Exception the exception + */ + public DataCatalogueRunningCluster(String scope) throws Exception{ + + if(scope == null || scope.isEmpty()) + throw new Exception("Invalid scope!!"); + + // retrieve the current scope and save it (it will be reset later) + String currentScope = ScopeProvider.instance.get(); + + logger.info("Retrieving ckan database service end point information for scope " + scope); + try { + + // set the scope + ScopeProvider.instance.set(scope); + + logger.debug("Retrieving database information."); + + List resources = getConfigurationFromISFORDB(); + evaluateRightConfigurationDB(resources); + + logger.debug("Retrieving ckan data catalogue service end point information and sysadmin token."); + + resources = getConfigurationFromISFORCatalogueUrl(); + evaluateRightConfigurationCatalogue(resources); + + // finally get the url in which the ckan portlet is deployed + + logger.debug("Looking for portlet url in " + ScopeProvider.instance.get() + " scope" ); + + //portletUrl = getPortletUrlFromInfrastrucure(); + mapAccessURLToCatalogue = getPortletUrlFromInfrastrucure(); + portletUrl = mapAccessURLToCatalogue.get(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PRIVATE_VRE); + + // and parse the CatalogueDelegateRole resource, if any, in this context + parseExtendingRoles(); + + }catch(Exception e) { + logger.warn("The following error occurred: " + e.toString()); + throw e; + }finally{ + ScopeProvider.instance.set(currentScope); + } + } + + + /** + * Evaluate the right configuration about ckan. + * + * @param resources the resources + * @throws NoDataCatalogueRuntimeResourceException the no data catalogue runtime resource exception + * @throws ServiceEndPointException the service end point exception + */ + private void evaluateRightConfigurationCatalogue( + List resources) throws NoDataCatalogueRuntimeResourceException, ServiceEndPointException { + if (resources.size() == 0){ + logger.error("There is no Runtime Resource having name " + RUNTIME_CATALOGUE_RESOURCE_NAME +" and Platform " + PLATFORM_CATALOGUE_NAME + " in this scope."); + throw new NoDataCatalogueRuntimeResourceException(); + } + else { + logger.debug(resources.toString()); + try{ + if(resources.size() > 1){ + boolean oneWasMaster = false; + + logger.info("Too many Runtime Resource having name " + RUNTIME_CATALOGUE_RESOURCE_NAME +" in this scope.. Looking for the one that has the property " + IS_MASTER_ROOT_KEY_PROPERTY); + + for (ServiceEndpoint res : resources) { + + Iterator accessPointIterator = res.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 + oneWasMaster = true; + + // add this host + datacatalogueUrls.add(accessPoint.address()); + + // retrieve sys admin token + sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value(); + sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken); + + // retrieve catalogue email + if(accessPoint.propertyMap().containsKey(CKAN_EMAIL_PROPERTY)){ + catalogueEmail = accessPoint.propertyMap().get(CKAN_EMAIL_PROPERTY).value(); + catalogueEmail = StringEncrypter.getEncrypter().decrypt(catalogueEmail); + } + + // retrieve URL_RESOLVER + if(accessPoint.propertyMap().containsKey(URL_RESOLVER)) + urlResolver = accessPoint.propertyMap().get(URL_RESOLVER).value(); + + // break now + break; + } + } + + // if none of them was master, throw an exception + if(!oneWasMaster) + throw new NoApplicationProfileMasterException("There is no application profile with MASTER property"); + + }else{ + + ServiceEndpoint res = resources.get(0); + Iterator accessPointIterator = res.profile().accessPoints().iterator(); + + while (accessPointIterator.hasNext()) { + ServiceEndpoint.AccessPoint accessPoint = accessPointIterator + .next(); + + // add this host + datacatalogueUrls.add(accessPoint.address()); + + // retrieve sys admin token + sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value(); + sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken); + + // retrieve catalogue email + if(accessPoint.propertyMap().containsKey(CKAN_EMAIL_PROPERTY)){ + catalogueEmail = accessPoint.propertyMap().get(CKAN_EMAIL_PROPERTY).value(); + catalogueEmail = StringEncrypter.getEncrypter().decrypt(catalogueEmail); + } + + // get the is manage product property + Property entry = accessPoint.propertyMap().get(IS_MANAGE_PRODUCT_ENABLED); + String isManageProduct = entry != null ? entry.value() : null; + + if(isManageProduct != null && isManageProduct.equals("true")){ + logger.info("Manage product is enabled in this scope"); + manageProductEnabled = true; + } + + // retrieve option to check if the social post has to be made + socialPost = true; // default is true + if(accessPoint.propertyMap().containsKey(SOCIAL_POST)) + if(accessPoint.propertyMap().get(SOCIAL_POST).value().trim().equalsIgnoreCase("false")) + socialPost = false; + + + // retrieve option for user alert + if(accessPoint.propertyMap().containsKey(ALERT_USERS_ON_POST_CREATION)) + if(accessPoint.propertyMap().get(ALERT_USERS_ON_POST_CREATION).value().trim().equalsIgnoreCase("true")) + alertUsers = true; + + // retrieve URL_RESOLVER + if(accessPoint.propertyMap().containsKey(URL_RESOLVER)) + urlResolver = accessPoint.propertyMap().get(URL_RESOLVER).value(); + + // retrieve url of the solr index for further queries + if(accessPoint.propertyMap().containsKey(SOLR_INDEX_ADDRESS)) + urlSolr = accessPoint.propertyMap().get(SOLR_INDEX_ADDRESS).value(); + + } + } + + }catch(Exception e){ + throw new ServiceEndPointException("There is no service end point for such information" + e.toString()); + } + } + + + } + + /** + * Retrieve the right DB information. + * + * @param resources the resources + * @throws ServiceEndPointException the service end point exception + * @throws NoDataCatalogueRuntimeResourceException the no data catalogue runtime resource exception + */ + private void evaluateRightConfigurationDB(List resources) throws ServiceEndPointException, NoDataCatalogueRuntimeResourceException { + + if (resources.size() == 0){ + throw new NoDataCatalogueRuntimeResourceException("There is no Runtime Resource having name " + RUNTIME_DB_RESOURCE_NAME +" and Platform " + PLATFORM_DB_NAME + " in this scope."); + } + else { + try{ + + if(resources.size() > 1){ + boolean oneWasMaster = false; + + logger.info("Too many Runtime Resource having name " + RUNTIME_DB_RESOURCE_NAME +" in this scope.. Looking for the one that has the property " + IS_MASTER_ROOT_KEY_PROPERTY); + + for (ServiceEndpoint res : resources) { + + Iterator accessPointIterator = res.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 + oneWasMaster = true; + + // add this host + hostsDB.add(accessPoint.address().split(":")[0]); + + // save the port + int port = Integer.parseInt(accessPoint.address().split(":")[1]); + portsDB.add(port); + + // save the name of the cluster (this should be unique) + nameDB = accessPoint.name(); + + // save user and password + passwordDB = StringEncrypter.getEncrypter().decrypt(accessPoint.password()); + userDB = accessPoint.username(); + + // now break + break; + } + } + + // if none of them was master, throw an exception + if(!oneWasMaster) + throw new NoApplicationProfileMasterException("There is no application profile with MASTER property"); + }else{ + logger.debug(resources.toString()); + ServiceEndpoint res = resources.get(0); + Iterator accessPointIterator = res.profile().accessPoints().iterator(); + + while (accessPointIterator.hasNext()) { + ServiceEndpoint.AccessPoint accessPoint = accessPointIterator + .next(); + + // add this host + hostsDB.add(accessPoint.address().split(":")[0]); + + // save the port + int port = Integer.parseInt(accessPoint.address().split(":")[1]); + portsDB.add(port); + + // save the name of the cluster (this should be unique) + nameDB = accessPoint.name(); + + // save user and password + passwordDB = StringEncrypter.getEncrypter().decrypt(accessPoint.password()); + userDB = accessPoint.username(); + + } + } + }catch(Exception e ){ + throw new ServiceEndPointException(e.toString()); + } + } + } + + /** + * Retrieve endpoints information from IS for DB. + * + * @return list of endpoints for ckan database + * @throws Exception the exception + */ + private static List getConfigurationFromISFORDB() throws Exception{ + + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_DB_RESOURCE_NAME +"'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_DB_NAME +"'"); + DiscoveryClient client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + return toReturn; + + } + + /** + * Retrieve endpoints information from IS for DataCatalogue URL. + * + * @return list of endpoints for ckan data catalogue + * @throws Exception the exception + */ + private static List getConfigurationFromISFORCatalogueUrl() throws Exception{ + + 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 client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + return toReturn; + + } + + /** + * Retrieve the url of the ckan portlet deployed into this scope + * updated by Francesco see Feature #18039. + * + * @return the portlet url from infrastrucure + */ + private static Map getPortletUrlFromInfrastrucure() { + + String scope = ScopeProvider.instance.get(); + logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " + APPLICATION_PROFILE_NAME + " scope: " + scope); + Map mapAccess = new HashMap(3); + try { + + Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + + " eq '" + APPLICATION_PROFILE_NAME + "'" + + "return $profile"); + + DiscoveryClient client = client(); + List appProfile = client.submit(q); + + if (appProfile == null || appProfile.size() == 0) + throw new ApplicationProfileNotFoundException("Your applicationProfile is not registered in the infrastructure"); + else { + 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); + + List currValue = null; + currValue = helper.evaluate("/Resource/Profile/Body/url/text()"); + if (currValue != null && currValue.size() > 0) { + logger.debug("Private portlet url found is " + currValue.get(0)); + //return currValue.get(0); + mapAccess.put(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PRIVATE_VRE, currValue.get(0)); + } + + currValue = null; + currValue = helper.evaluate("/Resource/Profile/Body/"+PUBLIC_VRE_CATALOGUE_URL+"/text()"); + if (currValue != null && currValue.size() > 0) { + logger.debug(PUBLIC_VRE_CATALOGUE_URL+" portlet url found is " + currValue.get(0)); + //return currValue.get(0); + mapAccess.put(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PUBLIC_VRE, currValue.get(0)); + } + + } + + } catch (Exception e) { + logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e); + } + + return mapAccess; + + } + + /** + * Parse the CatalogueDelegateRoles in this context. + * + * @throws ParserConfigurationException the parser configuration exception + * @throws SAXException the SAX exception + * @throws IOException Signals that an I/O exception has occurred. + */ + private void parseExtendingRoles() throws ParserConfigurationException, SAXException, IOException { + + Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + + " eq '" + CATALOGUE_EXTENDING_ROLES + "'" + + "return $profile"); + + DiscoveryClient client = client(); + List appProfile = client.submit(q); + + logger.debug("Resource for extending role has size " + appProfile.size()); + + if (appProfile == null || appProfile.size() == 0) + return; + else { + String profile = appProfile.get(0); + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Node node = docBuilder.parse(new InputSource(new StringReader(profile))).getDocumentElement(); + XPathHelper helper = new XPathHelper(node); + + // fetch delegate elements + NodeList delegates = helper.evaluateForNodes("/Resource/Profile/Body/delegates/delegate"); + if (delegates != null && delegates.getLength() > 0) { + + for(int i = 0; i < delegates.getLength(); i++){ + + Node nodeI = delegates.item(i); + + if(nodeI.getNodeType() == Node.ELEMENT_NODE) { + + Element elem = (Element)nodeI; + String role = elem.getElementsByTagName("sourceRole").item(0).getTextContent(); + String destOrg = elem.getElementsByTagName("destOrganization").item(0).getTextContent(); + String sourceOrg = elem.getElementsByTagName("sourceOrganization").item(0).getTextContent(); + + if(destOrg == null || sourceOrg == null){ + logger.warn("DestOrg or SourceOrg parameters missing"); + continue; + }else{ + String currentValueForKey = extendRoleInOrganization.get(sourceOrg); + + if(currentValueForKey == null) + currentValueForKey = ""; + else + currentValueForKey += TUPLES_SEPARATOR; + + currentValueForKey += destOrg + ROLE_ORGANIZATION_SEPARATOR + role; + extendRoleInOrganization.put(sourceOrg, currentValueForKey); + } + } + } + } + + } + + logger.debug("Extended role map in this scope is " + extendRoleInOrganization); + } + + /** + * Retrieve the ckan portlet url. + * + * @return the portletUrl + */ + public String getPortletUrl() { + return portletUrl; + } + + /** + * Retrieve data catalogue url. + * + * @return the data catalogue url + */ + public List getDataCatalogueUrl() { + return datacatalogueUrls; + } + + /** + * Get the hosts for such resource. + * + * @return the database hosts + */ + public List getDatabaseHosts() { + return hostsDB; + } + + /** + * Get the ports for such resource. + * + * @return the database ports + */ + public List getDatabasePorts() { + return portsDB; + } + + /** + * Get the database name. + * + * @return the data base name + */ + public String getDataBaseName() { + return nameDB; + } + + /** + * Get the database's user. + * + * @return the data base user + */ + public String getDataBaseUser() { + return userDB; + } + + /** + * Get the database's password. + * + * @return the data base password + */ + public String getDataBasePassword() { + return passwordDB; + } + + /** + * Gets the sys admin token. + * + * @return the sysAdminToken + */ + public String getSysAdminToken() { + return sysAdminToken; + } + + /** + * Is manager product enabled (e.g., for GRSF records) + * + * @return true, if is manage product enabled + */ + public boolean isManageProductEnabled() { + return manageProductEnabled; + } + + /** + * Get the url of the uri resolver for this instance/scope. + * + * @return the url resolver + */ + public String getUrlResolver() { + return urlResolver; + } + + /** + * Check if alert user members is enabled. + * + * @return true, if is alert enabled + */ + public boolean isAlertEnabled() { + return alertUsers; + } + + + /** + * Get roles to extend. + * + * @return Map + */ + public Map getExtendRoleInOrganization() { + return extendRoleInOrganization; + } + + /** + * Get the solr index base url. + * + * @return the url solr + */ + public String getUrlSolr() { + return urlSolr; + } + + + /** + * Gets the map access URL to catalogue. + * + * @return the map access URL to catalogue + */ + public Map getMapAccessURLToCatalogue() { + return mapAccessURLToCatalogue; + } + + + /** + * Get the catalogue email. Default is "catalogue@d4science.org" + * + * @return the email catalogue + */ + public String getEmailCatalogue() { + logger.debug("Read email from resource is " + catalogueEmail); + return catalogueEmail == null? DEFAULT_CATALOGUE_EMAIL : catalogueEmail; + } + + /** + * Checks if is social post enabled. + * + * @return true, if is social post enabled + */ + public boolean isSocialPostEnabled() { + return socialPost; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java new file mode 100644 index 0000000..9136507 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java @@ -0,0 +1,139 @@ +package org.gcube.datacatalogue.ckanutillibrary.server.utils; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Some utility methods used within the library. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CatalogueUtilMethods { + + private static final Logger logger = LoggerFactory.getLogger(CatalogueUtilMethods.class); + private final static String HTTPS = "https"; + private final static String HTTP = "http"; + + /** + * Maps the scope name to the ckan organization name + * Use getCKANOrganization() which uses current scope + * @return + */ + @Deprecated + public static String getOrganizationNameFromScope(String scope){ + if(scope == null || scope.isEmpty()) { + throw new IllegalArgumentException("scope cannot be null"); + } + ScopeBean scopeBean = new ScopeBean(scope); + return scopeBean.name().toLowerCase().replace(" ", "_").replace("-", "_"); + + } + + /** + * Get CKAN Organization name by using scope name + * + */ + public static String getCKANOrganization() { + ScopeBean scopeBean = new ScopeBean(ScopeProvider.instance.get()); + return scopeBean.name().toLowerCase().replace(" ", "_").replace("-", "_"); + } + + /** + * Ckan username has _ instead of . (that is, costantino.perciante -> costantino_perciante) + * @param owner + * @return + */ + public static String fromUsernameToCKanUsername(String username){ + if(username == null) + return null; + return username.trim().replaceAll("\\.", "_"); + } + + /** + * Liferay username has . instead of _ (that is, costantino_perciante -> costantino.perciante) + * @param owner + * @return + */ + public static String fromCKanUsernameToUsername(String ckanUsername){ + if(ckanUsername == null) + return null; + + return ckanUsername.trim().replaceAll("_", "."); + } + + /** + * Generate the catalogue's dataset name from its title + * @param title + * @return + */ + public static String fromProductTitleToName(String title) { + if(title == null) + return null; + + String regexTitleNameTransform = "[^A-Za-z0-9_-]"; + return title.trim().replaceAll(regexTitleNameTransform, "_").replaceAll("_+", "_").toLowerCase(); + } + + /** + * Convert a display group name to group id + * @param groupName + * @return + */ + public static String fromGroupTitleToName(String groupName){ + if(groupName == null) + return null; + + String regexGroupNameTransform = "[^A-Za-z0-9-]"; + String modified = groupName.trim().replaceAll(regexGroupNameTransform, "-").replaceAll("-+", "-").toLowerCase(); + + if(modified.startsWith("-")) + modified = modified.substring(1); + if(modified.endsWith("-")) + modified = modified.substring(0, modified.length() -1); + + return modified; + + } + + /** + * Utility method to check if a something at this url actually exists + * @param URLName + * @return + */ + public static boolean resourceExists(String URLName){ + + if(URLName == null || URLName.isEmpty()) + return false; + + try { + // replace https + String urlToTest = URLName.replace(HTTPS, HTTP); + HttpURLConnection.setFollowRedirects(true); + HttpURLConnection con = (HttpURLConnection) new URL(urlToTest).openConnection(); + con.setRequestMethod("HEAD"); + logger.debug("Return code is " + con.getResponseCode()); + return (con.getResponseCode() == HttpURLConnection.HTTP_OK); + } + catch (Exception e) { + logger.error("Exception while checking url", e); + return false; + } + } + + /** + * Builds a string made of key + scope + * @param key + * @param scope + * @return + */ + public static String concatenateSessionKeyScope(String key, String scope){ + if(key == null || scope == null) + throw new IllegalArgumentException("Key or scope null"); + return key.concat(scope); + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java new file mode 100644 index 0000000..a141eb9 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java @@ -0,0 +1,17 @@ +package org.gcube.datacatalogue.ckanutillibrary.server.utils; + +/** + * A list of attributes that are saved into http session. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class SessionCatalogueAttributes { + + // CKAN KEYS (PLEASE NOTE THAT MOST OF THESE INFO ARE SAVED INTO SESSION PER SCOPE) + public static final String CKAN_ORGS_USER_KEY = "ckanOrgs"; // organizations to whom he belongs (shown into the portlet) + public static final String CKAN_HIGHEST_ROLE = "ckanHighestRole"; // editor, member, admin + public static final String CKAN_ORGANIZATIONS_PUBLISH_KEY = "ckanOrganizationsPublish"; // here he can publish (admin/editor role) + public static final String CKAN_LICENSES_KEY = "ckanLicenses"; // licenses + public static final String CKAN_PROFILES_KEY = "ckanProfiles"; // product profiles + public static final String CKAN_GROUPS_MEMBER = "ckanGroupsMember"; + public static final String CKAN_GROUPS_USER_KEY = "ckanGroups"; // to show the list of groups in the portlet +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java new file mode 100644 index 0000000..947d1d0 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java @@ -0,0 +1,24 @@ +package org.gcube.datacatalogue.ckanutillibrary.server.utils.url; + +/** + * Entity context for uri resolver + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public enum EntityContext { + + DATASET("dataset"), + GROUP("group"), + ORGANIZATION("organization"); + + private String entityAsString; + + private EntityContext(String entityAsString) { + this.entityAsString = entityAsString; + } + + @Override + public String toString() { + return this.entityAsString; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java new file mode 100644 index 0000000..ccc7c49 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java @@ -0,0 +1,134 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * A CKan user. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CKanUserWrapper implements Serializable{ + + private static final long serialVersionUID = 6264706263035722775L; + + private String id; + private String name; + private String apiKey; + private long creationTimestamp; + private String about; + private String openId; + private String fullName; + private String email; + private boolean isAdmin; + + + public CKanUserWrapper() { + super(); + } + + /** Create a ckan user object. + * @param id + * @param name + * @param apiKey + * @param creationTimestamp + * @param about + * @param openId + * @param fullName + * @param email + * @param isAdmin + */ + public CKanUserWrapper(String id, String name, String apiKey, + long creationTimestamp, String about, String openId, + String fullName, String email, boolean isAdmin) { + super(); + this.id = id; + this.name = name; + this.apiKey = apiKey; + this.creationTimestamp = creationTimestamp; + this.about = about; + this.openId = openId; + this.fullName = fullName; + this.email = email; + this.isAdmin = isAdmin; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public long getCreationTimestamp() { + return creationTimestamp; + } + + public void setCreationTimestamp(long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + } + + public String getAbout() { + return about; + } + + public void setAbout(String about) { + this.about = about; + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isAdmin() { + return isAdmin; + } + + public void setAdmin(boolean isAdmin) { + this.isAdmin = isAdmin; + } + + @Override + public String toString() { + return "CKanUserExtended [id=" + id + ", name=" + name + ", apiKey=" + apiKey.substring(0, 5) + "****************" + + ", creationTimestamp=" + creationTimestamp + ", about=" + + about + ", openId=" + openId + ", fullName=" + fullName + + ", email=" + email + ", isAdmin=" + isAdmin + "]"; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java new file mode 100644 index 0000000..c5d12d8 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java @@ -0,0 +1,96 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.json.simple.JSONObject; + +/** + * A ckan dataset relationship. It is represented by the following fields + *
    + *
  • subject dataset id + *
  • object dataset id + *
  • type of the relationship + *
  • comment an optional comment + *
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CkanDatasetRelationship { + + private String subject; + private String object; + private String comment; + private String type; + + + public CkanDatasetRelationship(){ + super(); + } + + /** + * @param subject + * @param object + * @param comment + * @param type + */ + public CkanDatasetRelationship(String subject, String object, + String comment, String type) { + super(); + this.subject = subject; + this.object = object; + this.comment = comment; + this.type = type; + } + + /** + * From a json object that must have the properties listed in the class header (comment is optional) + * @param object + */ + public CkanDatasetRelationship(JSONObject object) { + this.comment = (String) object.get("comment"); + this.object = (String) object.get("object"); + this.subject = (String) object.get("subject"); + this.type = (String) object.get("type"); // TODO convert to one of enums DatasetRelationships + checkNotNull(object); + checkNotNull(subject); + checkNotNull(type); + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return "CkanDatasetRelationship [subject=" + subject + ", object=" + + object + ", comment=" + comment + ", type=" + type + + "]"; + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.java new file mode 100644 index 0000000..657fb09 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.java @@ -0,0 +1,27 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +/** + * Allowed relationships between packages(datasets). Some of them are not supported yet due to the problem + * reported here https://support.d4science.org/issues/4455 + *
    + *
  • depends_on + *
  • dependency_of + *
  • derives_from + *
  • has_derivation + *
  • child_of + *
  • parent_of + *
  • links_to + *
  • linked_from + *
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public enum DatasetRelationships { + depends_on, + dependency_of, + derives_from, + has_derivation, + child_of, + parent_of, + links_to, + linked_from +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java new file mode 100644 index 0000000..2e7695e --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java @@ -0,0 +1,57 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * This bean offers the following information: + *
    + *
  • landing page url to the items page (within the portlet) + *
  • landing page url to the orgs page (within the portlet) + *
  • landing page url to the groups page (within the portlet) + *
  • landing page url to the types page (within the portlet) + *
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class LandingPages implements Serializable { + + private static final long serialVersionUID = -5617896049674346109L; + private String urlTypes; + private String urlOrganizations; + private String urlGroups; + private String urlItems; + + public LandingPages() { + super(); + } + public String getUrlTypes() { + return urlTypes; + } + public void setUrlTypes(String urlTypes) { + this.urlTypes = urlTypes; + } + public String getUrlOrganizations() { + return urlOrganizations; + } + public void setUrlOrganizations(String urlOrganizations) { + this.urlOrganizations = urlOrganizations; + } + public String getUrlGroups() { + return urlGroups; + } + public void setUrlGroups(String urlGroups) { + this.urlGroups = urlGroups; + } + public String getUrlItems() { + return urlItems; + } + public void setUrlItems(String urlItems) { + this.urlItems = urlItems; + } + @Override + public String toString() { + return "LandingPages [urlTypes=" + urlTypes + ", urlOrganizations=" + + urlOrganizations + ", urlGroups=" + urlGroups + ", urlItems=" + + urlItems + "]"; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java new file mode 100644 index 0000000..2b124c3 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java @@ -0,0 +1,152 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * A bean that resembles the CKanResource bean object + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ResourceBean implements Serializable { + + private static final long serialVersionUID = -5275448097250176185L; + private String url; + private String name; + private String description; + private String id; + private String owner; + private String datasetId; + private String mimeType; + + public ResourceBean(){ + super(); + } + + /** + * @param url + * @param name + * @param description + * @param id + * @param owner + * @param datasetId + * @param mimeType + */ + public ResourceBean(String url, String name, String description, String id, + String owner, String datasetId, String mimeType) { + super(); + this.url = url; + this.name = name; + this.description = description; + this.id = id; + this.owner = owner; + this.datasetId = datasetId; + this.mimeType = mimeType; + } + + /** + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * @param url the url to set + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the owner + */ + public String getOwner() { + return owner; + } + + /** + * @param owner the owner to set + */ + public void setOwner(String owner) { + this.owner = owner; + } + + /** + * @return the datasetId + */ + public String getDatasetId() { + return datasetId; + } + + /** + * @param datasetId the datasetId to set + */ + public void setDatasetId(String datasetId) { + this.datasetId = datasetId; + } + + /** + * @return the mimeType + */ + public String getMimeType() { + return mimeType; + } + + /** + * @param mimeType the mimeType to set + */ + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ResourceBean [url=" + url + ", name=" + name + ", description=" + + description + ", id=" + id + ", owner=" + owner + + ", datasetId=" + datasetId + ", mimeType=" + mimeType + "]"; + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java new file mode 100644 index 0000000..196b655 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java @@ -0,0 +1,39 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +/** + * Roles that user can have into organizations/groups. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public enum RolesCkanGroupOrOrg{ + MEMBER, + EDITOR, + ADMIN; + + public static String convertToCkanCapacity(RolesCkanGroupOrOrg role){ + + if(role == null) + return null; + else + return role.toString().toLowerCase(); + + } + + public static RolesCkanGroupOrOrg convertFromCapacity(String capacity){ + + if(capacity == null) + return null; + else + return RolesCkanGroupOrOrg.valueOf(capacity.toUpperCase()); + + } + + /** + * Get the higher role between role1 and role2 + * @param role1 + * @param role2 + * @return the higher role + */ + public static RolesCkanGroupOrOrg getHigher(RolesCkanGroupOrOrg role1, RolesCkanGroupOrOrg role2){ + return role1.ordinal() > role2.ordinal() ? role1 : role2; + } +} \ No newline at end of file diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/State.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/State.java new file mode 100644 index 0000000..ddc8fc2 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/State.java @@ -0,0 +1,10 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +/** + * The current state of this group/user + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +public enum State{ + DELETED, ACTIVE +} \ No newline at end of file diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java new file mode 100644 index 0000000..fee060d --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java @@ -0,0 +1,54 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * This bean offers the following statistics: + *
    + *
  • number of items of the catalogue + *
  • number of organizations of the catalogue + *
  • number of groups of the catalogue + *
  • number of types of the catalogue + *
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class Statistics implements Serializable{ + + private static final long serialVersionUID = 2871906712366452266L; + private long numTypes; + private long numOrganizations; + private long numGroups; + private long numItems; + + public long getNumTypes() { + return numTypes; + } + public void setNumTypes(long numTypes) { + this.numTypes = numTypes; + } + public long getNumOrganizations() { + return numOrganizations; + } + public void setNumOrganizations(long numOrganizations) { + this.numOrganizations = numOrganizations; + } + public long getNumGroups() { + return numGroups; + } + public void setNumGroups(long numGroups) { + this.numGroups = numGroups; + } + public long getNumItems() { + return numItems; + } + public void setNumItems(long numItems) { + this.numItems = numItems; + } + @Override + public String toString() { + return "Statistics [numTypes=" + numTypes + ", numOrganizations=" + + numOrganizations + ", numGroups=" + numGroups + ", numItems=" + + numItems + "]"; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java new file mode 100644 index 0000000..384b652 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java @@ -0,0 +1,12 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +@SuppressWarnings("serial") +/** + * Thrown when no application profile with such information is found + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ApplicationProfileNotFoundException extends Exception { + public ApplicationProfileNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java new file mode 100644 index 0000000..feca2ae --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java @@ -0,0 +1,20 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +/** + * Thrown when there are more than one application profile, but none of them was set as master + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class NoApplicationProfileMasterException extends Exception { + + private static final long serialVersionUID = 5874713540422734005L; + private static final String DEFAULT_MESSAGE = "There is more than one application profile into this scope" + + " but none of them is set as master!"; + + public NoApplicationProfileMasterException(){ + super(DEFAULT_MESSAGE); + } + + public NoApplicationProfileMasterException(String message) { + super(message); + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.java new file mode 100644 index 0000000..1f35604 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.java @@ -0,0 +1,21 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +/** + * No Data Catalogue node found. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +public class NoDataCatalogueRuntimeResourceException extends Exception { + + private static final long serialVersionUID = -40748130477807648L; + + private static final String DEFAULT_MESSAGE = "No Data Catalogue instance for this scope!"; + + public NoDataCatalogueRuntimeResourceException(){ + super(DEFAULT_MESSAGE); + } + + public NoDataCatalogueRuntimeResourceException(String message) { + super(message); + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java new file mode 100644 index 0000000..bfcecaf --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java @@ -0,0 +1,19 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +/** + * Exception thrown when it is not possible retrieve information from the ServiceEndpoint + * related to the Data Catalogue + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ServiceEndPointException extends Exception { + + private static final long serialVersionUID = 7057074369001221035L; + private static final String DEFAULT_MESSAGE = "Unable to retrieve information from Data Catalogue endpoint!"; + + public ServiceEndPointException(){ + super(DEFAULT_MESSAGE); + } + public ServiceEndPointException(String string) { + super(string); + } +} diff --git a/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.java b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.java new file mode 100644 index 0000000..4f73f02 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.java @@ -0,0 +1,22 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +/** + * Too many clusters in this scope exception. + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + * + */ +public class TooManyRunningClustersException extends Exception { + + private static final long serialVersionUID = -7847493730006647045L; + private static final String DEFAULT_MESSAGE = "Too many CKan data catalague instances for this scope!"; + + public TooManyRunningClustersException(){ + super(DEFAULT_MESSAGE); + } + + public TooManyRunningClustersException(String message) { + super(message); + } + +} diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF new file mode 100644 index 0000000..0048ac8 --- /dev/null +++ b/target/classes/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Built-By: francesco +Build-Jdk: 1.8.0_252 +Specification-Title: CKan utility library +Specification-Version: 0.1.0-SNAPSHOT +Implementation-Title: CKan utility library +Implementation-Version: 0.1.0-SNAPSHOT +Implementation-Vendor-Id: org.gcube.datacatalogue +Build-Time: 20200601-134620 +Created-By: Maven Integration for Eclipse +SCM-Branch: +SCM-Revision: +SCM-Revision-URL: https://code-repo.d4science.org/gCubeSystem/catalogu + e-util-library/commit/${buildNumber} + diff --git a/target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.properties b/target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.properties new file mode 100644 index 0000000..c1f2a7e --- /dev/null +++ b/target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.properties @@ -0,0 +1,7 @@ +#Generated by Maven Integration for Eclipse +#Mon Jun 01 15:46:21 CEST 2020 +version=0.1.0-SNAPSHOT +groupId=org.gcube.datacatalogue +m2e.projectName=catalogue-util-library +m2e.projectLocation=/home/francesco/git/catalogue-util-library +artifactId=catalogue-util-library diff --git a/target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.xml b/target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.xml new file mode 100644 index 0000000..668791f --- /dev/null +++ b/target/classes/META-INF/maven/org.gcube.datacatalogue/catalogue-util-library/pom.xml @@ -0,0 +1,228 @@ + + 4.0.0 + + + maven-parent + org.gcube.tools + 1.1.0 + + + + org.gcube.datacatalogue + catalogue-util-library + 0.1.0-SNAPSHOT + + CKan utility library + + Utility library to retrieve users information, organizations information and so on from the ckan d4science datacatalogue + + + + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + https://code-repo.d4science.org/gCubeSystem/${project.artifactId} + + + + data-catalogue + 0.4.2 + 9.4.1208.jre7 + UTF-8 + UTF-8 + 2.7.0 + + + + + + org.gcube.distribution + maven-portal-bom + LATEST + pom + import + + + + + + + com.google.gwt + gwt-user + provided + + + + + eu.trentorise.opendata + jackan + ${jackanVersion} + compile + + + + org.gcube.data-publishing + gcat-client + [1.0.0, 2.0.0-SNAPSHOT) + compile + + + + + + + + + + + junit + junit + 4.8 + test + + + org.gcube.common.portal + portal-manager + provided + + + org.gcube.resources.discovery + ic-client + provided + + + org.gcube.core + common-scope-maps + provided + + + + org.gcube.core + common-encryption + provided + + + org.gcube.dvos + usermanagement-core + provided + + + net.htmlparser.jericho + jericho-html + 3.3 + compile + + + com.google.guava + guava + + + com.googlecode.json-simple + json-simple + compile + + + org.apache.solr + solr-solrj + [4.10.2,5.0.0) + + + org.slf4j + slf4j-log4j12 + provided + + + org.slf4j + slf4j-api + provided + + + + + + + src/main/java + + **/*.* + + + + + + maven-compiler-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + true + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + ${distroDirectory}/descriptor.xml + + + + fully.qualified.MainClass + + + + + + servicearchive + install + + single + + + + + + + diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml b/target/classes/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml new file mode 100644 index 0000000..a3990ca --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/CkanUtilLibrary.gwt.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.class new file mode 100644 index 0000000000000000000000000000000000000000..91f6d884263958f9f875190eddac5b9bc74f9a28 GIT binary patch literal 8469 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 literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java new file mode 100644 index 0000000..43a2fce --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/ExtendCkanClient.java @@ -0,0 +1,240 @@ +/** + * + */ +package org.gcube.datacatalogue.ckanutillibrary.ckan; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URLEncoder; +import java.util.Arrays; + +import javax.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; + +import eu.trentorise.opendata.jackan.CheckedCkanClient; +import eu.trentorise.opendata.jackan.exceptions.CkanException; +import eu.trentorise.opendata.jackan.exceptions.JackanException; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Request; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.fluent.Response; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanOrganization; +import eu.trentorise.opendata.jackan.model.CkanResponse; + + +/** + * The Class ExtendCkanClient. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Jun 14, 2019 + */ +public class ExtendCkanClient extends CheckedCkanClient implements PatchedCkan{ + + private static final Logger logger = LoggerFactory.getLogger(ExtendCkanClient.class); + + @Nullable + private static ObjectMapper objectMapper; + + private String catalogueURL; + private String ckanToken; + private int extendTimeout = 120000; //in milliseconds + + + /** + * Instantiates a new extend ckan client. + * + * @param catalogueURL the catalogue url + */ + public ExtendCkanClient(String catalogueURL) { + super(catalogueURL); + this.catalogueURL = catalogueURL; + + } + + /** + * Instantiates a new extend ckan client. + * + * @param catalogueURL the catalogue url + * @param ckanToken the ckan token + */ + public ExtendCkanClient(String catalogueURL, @Nullable String ckanToken) { + super(catalogueURL, ckanToken); + this.catalogueURL = catalogueURL; + this.ckanToken = ckanToken; + } + + /** + * Instantiates a new extend ckan client. + * + * @param catalogueURL the catalogue url + * @param ckanToken the ckan token + * @param timeout the timeout + */ + public ExtendCkanClient(String catalogueURL, @Nullable String ckanToken, int timeout) { + super(catalogueURL, ckanToken); + this.catalogueURL = catalogueURL; + this.ckanToken = ckanToken; + this.extendTimeout = timeout; + } + + + /** + * Configures the request. Should work both for GETs and POSTs. + * + * @param request the request + * @return the request + */ + @Override + protected Request configureRequest(Request request) { + request = super.configureRequest(request); + + logger.debug("Setting timeout to {}", extendTimeout); + + request.socketTimeout(this.extendTimeout) + .connectTimeout(this.extendTimeout); + + return request; + } + + /** + * Gets the catalogue url. + * + * @return the catalogueURL + */ + public String getCatalogueURL() { + + return catalogueURL; + } + + + /** + * Gets the ckan token. + * + * @return the ckanToken + */ + @Override + public String getCkanToken() { + + return ckanToken; + } + + /** + * Gets the timeout. + * + * @return the timeout + */ + public int getTimeout() { + return extendTimeout; + } + + /* (non-Javadoc) + * @see eu.trentorise.opendata.jackan.CkanClient#getOrganization(java.lang.String) + */ + public synchronized CkanOrganization getOrganization(String idOrName) { + checkNotNull(idOrName, "Need a valid id or name!"); + logger.info("Patched read organization for id/name: {}", idOrName); + return getHttp(OrganizationResponse.class, "/api/3/action/organization_show", "id", idOrName, + "include_datasets", "false", "include_users", "true").result; + + } + + + /* (non-Javadoc) + * @see eu.trentorise.opendata.jackan.CkanClient#getGroup(java.lang.String) + */ + public synchronized CkanGroup getGroup(String idOrName) { + checkNotNull(idOrName, "Need a valid id or name!"); + logger.info("Patched read group for id/name: {}", idOrName); + return getHttp(GroupResponse.class, "/api/3/action/group_show", "id", idOrName, "include_datasets", + "false", "include_users", "true").result; + } + + + /** + * Retrieves the Jackson object mapper for reading operations. Internally, + * Object mapper is initialized at first call. + * + * @return the object mapper + */ + static ObjectMapper getObjectMapper() { + if (objectMapper == null) { + objectMapper = new ObjectMapper(); + configureObjectMapper(objectMapper); + } + return objectMapper; + } + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#getHttp(java.lang.Class, java.lang.String, java.lang.Object[]) + */ + public T getHttp(Class responseType, String path, Object... params) { + + checkNotNull(responseType); + checkNotNull(path); + String fullUrl = calcFullUrl(path, params); + T ckanResponse; + String returnedText; + + try { + + logger.debug("getting {}", fullUrl); + Request request = Request.Get(fullUrl); + configureRequest(request); + Response response = request.execute(); + InputStream stream = response.returnResponse() + .getEntity() + .getContent(); + + try (InputStreamReader reader = new InputStreamReader(stream, Charsets.UTF_8)) { + returnedText = CharStreams.toString(reader); + } + + logger.trace("returnedText {}", returnedText); + } catch (Exception ex) { + throw new CkanException("Error while performing GET. Request url was: " + fullUrl, this, ex); + } + try { + ckanResponse = getObjectMapper().readValue(returnedText, responseType); + } catch (Exception ex) { + throw new CkanException( + "Couldn't interpret json returned by the server! Returned text was: " + returnedText, this, ex); + } + + if (!ckanResponse.isSuccess()) { + throwCkanException("Error while performing GET. Request url was: " + fullUrl, ckanResponse); + } + return ckanResponse; + } + + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#calcFullUrl(java.lang.String, java.lang.Object[]) + */ + public String calcFullUrl(String path, Object[] params) { + checkNotNull(path); + + try { + StringBuilder sb = new StringBuilder().append(catalogueURL) + .append(path); + for (int i = 0; i < params.length; i += 2) { + sb.append(i == 0 ? "?" : "&") + .append(URLEncoder.encode(params[i].toString(), "UTF-8")) + .append("=") + .append(URLEncoder.encode(params[i + 1].toString(), "UTF-8")); + } + return sb.toString(); + } catch (Exception ex) { + throw new JackanException("Error while building url to perform GET! \n path: " + path + " \n params: " + + Arrays.toString(params), ex); + } + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan$GroupResponse.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/PatchedCkan$GroupResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..16dfde15e7e2f97081634bbee75556b6fb457364 GIT binary patch literal 588 zcmb_ZO-lnY5Ph-Ru3fjb){nd3K|L5jkb>f+P!$#tmEN=4p-oLUCD{o6EKh<5e}F$q z%&rymCL$s8kvDH9ym@N}->Dhc-1$N;WI#zw#t_@CW## z#O%^Sk0KH>nKzGlGrW9#e|!Qs!FGTO!;P^cK1%b1_)s{J`m4++C!RhDoja+NOsudk zCFXa+rDGcQJh#`kBcbK1aMI{|%4SAq6rjd%OgVR!v@=#_#LbL!A&cbEv!n@$eV9m#<%KHd9c!>rhxN=p7W*n?7>2yeR=WDs}0emRq zVbm~2Vh|TIC+E_ye@{|(>i48xwWArFJ3BY9Ui5zwbhm`EPn37xn|si;`3#B`8uFufhIv=I$O2o0B3ACJzbm-q? zLLUf!`&=g6S*e||Q7pOXOFh)adtxYx-=`$2tQK*GWtYjD*wh#W! zIQk*?u-*2LCe%!&3=4r!K_gM>+A4!G#vWD}8q*HmX1eFs z)iW%9^F6FFTujZ*_Gz?5ZCp6dz%WZs3CQK1Fo!((9(gk;(9 the generic type + * @param responseType a descendant of CkanResponse + * @param path something like /api/3/package_show + * @param params list of key, value parameters. They must be not be url + * encoded. i.e. "id","laghi-monitorati-trento" + * @return the http + * @throws CkanException on error + */ + public T getHttp(Class responseType, String path, Object... params); + + /** + * + * This method is private in {@link CkanClient} so I need to rewrite it + * + * + * Calculates a full url out of the provided params. + * + * @param path something like /api/3/package_show + * @param params list of key, value parameters. They must be not be url encoded. + * i.e. "id","laghi-monitorati-trento" + * @return the full url to be called. + * @throws JackanException if there is any error building the url + */ + public String calcFullUrl(String path, Object[] params); + + + + // WE NEED TO OVERRIDE THE FOLLOWING METHODS + + /** + * Gets the organization. + * + * @param idOrName the id or name + * @return the organization + */ + public CkanOrganization getOrganization(String idOrName); + + /** + * Gets the group. + * + * @param idOrName the id or name + * @return the group + */ + public CkanGroup getGroup(String idOrName); + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/ckan/SimpleExtendCkanClient.class new file mode 100644 index 0000000000000000000000000000000000000000..bd71c39c33c511db3dd1dab5ed81011b398658f1 GIT binary patch literal 7454 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 T getHttp(Class responseType, String path, Object... params) { + + checkNotNull(responseType); + checkNotNull(path); + String fullUrl = calcFullUrl(path, params); + T ckanResponse; + String returnedText; + + try { + + logger.debug("getting {}", fullUrl); + Request request = Request.Get(fullUrl); + configureRequest(request); + Response response = request.execute(); + InputStream stream = response.returnResponse() + .getEntity() + .getContent(); + + try (InputStreamReader reader = new InputStreamReader(stream, Charsets.UTF_8)) { + returnedText = CharStreams.toString(reader); + } + + logger.trace("returnedText {}", returnedText); + } catch (Exception ex) { + throw new CkanException("Error while performing GET. Request url was: " + fullUrl, this, ex); + } + try { + ckanResponse = getObjectMapper().readValue(returnedText, responseType); + } catch (Exception ex) { + throw new CkanException( + "Couldn't interpret json returned by the server! Returned text was: " + returnedText, this, ex); + } + + if (!ckanResponse.isSuccess()) { + throwCkanException("Error while performing GET. Request url was: " + fullUrl, ckanResponse); + } + return ckanResponse; + } + + + /* (non-Javadoc) + * @see org.gcube.datacatalogue.ckanutillibrary.server.patch.PatchedCkan#calcFullUrl(java.lang.String, java.lang.Object[]) + */ + public String calcFullUrl(String path, Object[] params) { + checkNotNull(path); + + try { + StringBuilder sb = new StringBuilder().append(catalogueURL) + .append(path); + for (int i = 0; i < params.length; i += 2) { + sb.append(i == 0 ? "?" : "&") + .append(URLEncoder.encode(params[i].toString(), "UTF-8")) + .append("=") + .append(URLEncoder.encode(params[i + 1].toString(), "UTF-8")); + } + return sb.toString(); + } catch (Exception ex) { + throw new JackanException("Error while building url to perform GET! \n path: " + path + " \n params: " + + Arrays.toString(params), ex); + } + } + + /** + * Gets the catalogue url. + * + * @return the catalogueURL + */ + public String getCatalogueURL() { + + return catalogueURL; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.class new file mode 100644 index 0000000000000000000000000000000000000000..ab428406cc26cb503652277fc473f8f4816330e5 GIT binary patch literal 6228 zcmdT}X>=Ra75>JSJhD6?!C8nyfQdqg?IacuR%ZdP;KY^_uY@J(NSes9WsMj~Neo?} zEre1Efk4>_h0?GU62OU_6ewMwEQPidN*B8Cd;6omdYXRk&1mtG13hieY2#S)=Dzpt zyW4l~eex^+IP@HVmH4ZQ5(O(QI~I&ZvSBkAH8MtozX>arHG`2MBbm*_6Nz}(HtdmL zG#qShY%&rF(^lb8Fl*4*W&{&PG8XI%51NsTg3|WR3lvng3zq4`)-wi!?N%&i+N%^) zG_7w4ZE0@Y(%aQ8mJ~L3XY6<~#wA*A$%f9Z9tE?D*0d!vro$({DAdr=QnaVHyQPaV zGZ0ask)X!!F&x~lqs0m9#5K~>~Pq$dyH_xl*Wk|i9W-Qi+7h; zwpvQ)M=4Iwa6D#G%FIAKt>8?_|6gpgE&j4Kv_l1VoA>K+C;3&d$HOZq3cQZq2=J$h&n0{nBJ5lZ?B# zm82W1YaC_LmnVXS37W#+vLj-q#HzH4GZf5~p(mDgZ*0%csW?l4UWiKR-jJ1PwX(@* zew7dB(1lH%p-@XxPg`e5?`qlD+tS@rfqJY~!P90<4krz3z}WLf&2Tox)2DGvO`i|v zbBbH*QdT+>vrURu*KEhPnYJH|Xjak0V45VIh8DCcP`6rk$QWj9O^8p|d#+U^Or4PR z;X(y-2BYCfec`bBU~oy=k9BBQv3>%!9X=X55K>UavxW^K{oHBPxTGkWoQyzt6l8V< zQn7*FnoMrY#uHJY>^gL5=mznxZZi^DvvVt>s`#*@bM~VXeF8pfeYi-0QZEP>Yq$iL zQgS1eGLumSD~g#-V#TN*wWr_v+t`99El zO3;rO;wlCd%#-#JG3o?Chmkax|1_M6K?NPts4&&gQz=J7$n0pi(MX#G)W{s|j}*ac zuET8#xMp;-WDIo}DL0eNB`hznt!ygYIMSOo?N-|wZf;btcp8yiaYT&?k^{k0-W`u6 zjZD_2Ij(%~9jm9R_`cI+dcd&FXt2vlnCT`~Iw^Fg-D$^Gt)4Yo=1MB_58XxNS&tVNLlGcv@S5y~bK?;W*n1gW?}!Licc(h?UM z=>b~9j}e^UXG;B$aQbOJd_=+Dx?9?rcl1C^Sa?f38dx5P7%3wX&x{20)~?PDJ&?+V z6Y)r(E--A0suR%Hb+(0y$Z~5yXX?tWs4KA3*SNg7pWOBB1Ey{2fs80s;E=|(b| zBP5x00&A9L>E@*l-957|kj@wxF~?HM9OlkCN598pJiUc!&`8FwFobP+jgP7L zC|iO&EDEuz;p4c587pO*DY}&Lm@$XVBy-fMM~@&8$8@3C5Y6x4K|ApY71t?PkUwb3 zDh=1;lML0gnaN>#UUl2lNUZ4->^`O8M%=_A#N~|^gUw*A@>aK9>`dRR;TG&>=$Jdq zNH$|`%$oKH;h#$qLe4HTolRuA&CDtvZeuRVIllt8<4zTKups57&9BvP7w&etmzB-0)R!(X`(B z_Yb94AHrT0pHncSfHERX!^3!lO<^j_SUIQobQhULKAk4pyCmU-$22^S&$DMsnmfpg zZRW*3JgK0e)rcp|sGhNO+hmt(ZZq}FfT>FlrUiNXfHf>h0z`V)OjyZSx=wGgZOhi< zY2AFa;NpLdG>5!eKTLk%U#8 z=GmvZYER1RqD?LnBDJw#vUqiw%*hPgnT|<{GIoj0CUuTOo*1kQzCkOVbR+s$7oG*Q zDOgz8HU(uY1`3OSTXrU@&AEB)R&f_SlFD_`v56A?*D8dHmnZn7XTY|$J01Q)x`SmT zpTZ_pLQx?bQt|cXh=~7Q8d>DgNfGG6(^00lQh|We$ zmqE3LL9`Cv(C|$WqG~+dGMvhchzj?nhHv97!a~-q20NB@@}{Sn*~y3Ru*=I89C9Vo zT#XTY1A703EnO{oz^MXmVQ};Qc}!K`l|7f(=EL_HMbudeCZu^+!w>NzkwmlMw7mX_ zoY&Sit#&_Aut@J{=w9E_yrQRbeM=}0rf5M+AAZL6y*DXbFad89Y$4$B3jvQ`DyS_+ z{8W4A9lA<@!6#I9{N$B7@;XDC^yHD@rSAzaEEdl?ppTO~&&;^rlvym!ebZ(Z`qJC}U&#>J

Pr8 zKah`yx|btB9TsCYPNt|!NIgZKx7Ok5o=5IjMs0n#^*|$DXsJt=fsZTr*K^5+2c631eNEFp`pL>0?)H3-Beop3>I~dp{<>R z#V_K-!|2?!Yz!L@qPMdD05%Eo0bF(fA80S0iaJwE_z+XexNIqZYsRp(WBEQFSSmdc zpm3mIehM^;A}zw%sKz;HV(4zhY7F6gslM(A>8ig7?VJ(n4^fo_hWVK!A5#8~CY6v= zU?D~7<)oIt7OE;Q&>-TpJrqCPe;6a14&urVB}6}cFjV>Bdhd!V?>Me1L48?OnP=HJ zuBD7+-qLa0AO_>urJ&xk7bh*R@>JeBj!!d~JeBvz!5Hov$7f5?U*#FcqYCai^6p-o zUhkn*g;gq_pt-6%2e8kv$2dkyP`lzF#*}^asvK0Q&&wx`Q^H`}ia3kmO!ibaQe=-b zRv*8k0af>61HWU~$k`suK|ki>Qbx^XjEK!R16z0lH)ys9sRsFMrIBLfGl&~7KyGpD z;`laF@8I)Znoq!>%P~zpzV_e?(!ev=u|13Dq)fY{sY}Vf2G8S*lxjXgc!BG@Jii%V z!j~CaLyX?9;H#W{k$eSC93C%`hj3CoyhkXWszRZsR6L~OY8AK3@lN3QBi!RDo)qi$ zM^$`HeC6`Wf6A@&)BluPx6_CtG}RS!>xbypt7zP7Xx3}#)}3_gbu|0+wA&4I>-BW% zO*Hf_&g>@TX1etjzU`)4Z>3vz)2+AtU%B;Fyhi5|r6tGE4kF3FlY`FJ37us**f2dw z^pfz#olr~n!s8jkx0H}l?{RSa_R(;>+y%6QW3@_^K)n-ZRjHNlNDvp``aKEP(pmlk z_yLcu{4qa@WvKGhmpiB}-&gO=N&3@*q#~32ywrjCUd*WXIjeooEBlzqPQ(4|#`nwT zYt;2&0!BQYoEWC(fxG#6AB)W%ruPS!&L8CJy*LYx5I~O-Y>)9Ps>jiXCkXf_3F>`p zarWaLjFR^u-T_9*^&nS{k@q2TAIIx_zKO$ln}8OOzm&y>cFsfo9sEi{UeJEcQ3+3d z)P=k_`!}R{czP1Qm5^^n)P?*Ow8?~^a{U4cey@ajBg(4JSB^0M`f`9K;E8sA^8Zf4 z9yr49P`#6;CFCO#@+G2~cVdIMD3x_!!Lk=Ip9%VR3dNe)AxhUD>0TOqKUaDfKQlOT ztT~VI1iVD*%cQ@;;`%C+=^N4lPE}cux4;6at->`GQVS@n{b#Z&!C(Ff DR+nKd literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java new file mode 100644 index 0000000..7be49c9 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/db/DBCaller.java @@ -0,0 +1,209 @@ +package org.gcube.datacatalogue.ckanutillibrary.db; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DBCaller { + + private static final Logger LOG = LoggerFactory.getLogger(DBCaller.class); + + private String CKAN_DB_URL; + private Integer CKAN_DB_PORT; + private String CKAN_DB_NAME; + private String CKAN_DB_USER; + private String CKAN_DB_PASSWORD; + + public DBCaller() { + } + + public DBCaller(String cKAN_DB_URL, Integer cKAN_DB_PORT, String cKAN_DB_NAME, String cKAN_DB_USER, + String cKAN_DB_PASSWORD) { + CKAN_DB_URL = cKAN_DB_URL; + CKAN_DB_PORT = cKAN_DB_PORT; + CKAN_DB_NAME = cKAN_DB_NAME; + CKAN_DB_USER = cKAN_DB_USER; + CKAN_DB_PASSWORD = cKAN_DB_PASSWORD; + } + + + /** + * Retrieve connection from the pool + * @return a connection available within the pool + * @throws SQLException + * @throws ClassNotFoundException + */ + private Connection getConnection() throws SQLException, ClassNotFoundException{ + + LOG.debug("CONNECTION REQUEST"); + // create db connection + Class.forName("org.postgresql.Driver"); + + String dbBaseConnectionURL = String.format("jdbc:postgresql://%s", CKAN_DB_URL); + + if(CKAN_DB_PORT!=null) + dbBaseConnectionURL+=":" + CKAN_DB_PORT; + + dbBaseConnectionURL+="/" + CKAN_DB_NAME; + + Connection connection = DriverManager.getConnection(dbBaseConnectionURL, CKAN_DB_USER, CKAN_DB_PASSWORD); + +// Connection connection = DriverManager.getConnection( +// "jdbc:postgresql://" + CKAN_DB_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD); + return connection; + + } + + /** + * Retrieve the map (groups id, capacity) with the groups to which the user belongs by querying directly the database. + * @param username + * @return + * @throws SQLException + * @throws ClassNotFoundException + */ + public Map getGroupsByUserFromDB(String userId){ + checkNotNull(userId); + + //couples (groups id, capacity) of the user in the group + + Map toReturn = new HashMap(); + Connection connection = null; + try{ + + connection = getConnection(); + ResultSet rs; + + String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" " + + "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?" + + " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;"; + + + PreparedStatement preparedStatement = connection.prepareStatement(joinQuery); + preparedStatement.setString(1, userId); + preparedStatement.setBoolean(2, false); + rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity"))); + } + + }catch(Exception e){ + LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage()); + return null; + }finally{ + closeConnection(connection); + } + return toReturn; + } + + /** + * Retrieve the map (organisation id, capacity) with the organisations to which the user belongs by querying directly the database. + * @param username + * @return + * @throws SQLException + * @throws ClassNotFoundException + */ + public Map getOrganizationsByUserFromDB(String userId){ + checkNotNull(userId); + + Map toReturn = new HashMap(); + Connection connection = null; + try{ + + connection = getConnection(); + ResultSet rs; + + String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" " + + "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?" + + " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;"; + + + PreparedStatement preparedStatement = connection.prepareStatement(joinQuery); + preparedStatement.setString(1, userId); + preparedStatement.setBoolean(2, true); + rs = preparedStatement.executeQuery(); + + while (rs.next()) { + + toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity"))); + } + + }catch(Exception e){ + LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage()); + return null; + }finally{ + closeConnection(connection); + } + return toReturn; + } + + + public String getApiKeyFromUsername(String username, String state) { + + LOG.debug("Request api key for user = " + username); + + // checks + checkNotNull(username); + checkArgument(!username.isEmpty()); + + // the connection + Connection connection = null; + String apiToReturn = null; + + try{ + + connection = getConnection(); + + String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;"; + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setString(1, username); + preparedStatement.setString(2, state); + + ResultSet rs = preparedStatement.executeQuery(); + while (rs.next()) { + apiToReturn = rs.getString("apikey"); + LOG.debug("Api key "+apiToReturn.substring(0,10)+" MASKED-TOKEN retrieved for user " + username); + break; + } + + return apiToReturn; + + }catch(Exception e){ + LOG.error("Unable to retrieve key for user " + username, e); + }finally{ + closeConnection(connection); + } + + return null; + } + + + /** + * Tries to close a connection + * @param connection + */ + private void closeConnection(Connection connection){ + + if(connection != null){ + try{ + connection.close(); + }catch(Exception e){ + LOG.error("Unable to close this connection ", e); + } + } + + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.class new file mode 100644 index 0000000000000000000000000000000000000000..19c51a32b26b39273687881e5a13d43ce6eb69fa GIT binary patch literal 2096 zcmb_d`%@cL7(F*omZV!~Q=pbw8mb_HwyQ$H8pM_qkQ$&iZ4}=(n@e2W>@vF>htBv% z`6^VIas1gos?&2f3&|jkbjHl&KE8Xu^S#df_U{*e{0U$hRRbx3IX|ddb-P(rR!v6I z=HK<}O=a2NORpI@uIp3-89e138Cfeu85O1Ls=z?E!1-fq(XsL8s8(PyUJB=MzE$v3itF>VY0_Kr(Pac&7vZc25auhgTop-uQ8!P%qTMXT; znQg1&*Xt_aQSZF%I-V0P@YY1WBG6s*Ybt|&TrhB6;L>rOWobu#@YF;W7X{LF6}7Mg z#wI#!7hM^Kh5SEFrXetBB8`kdf64LGdb3eg!DCrToWk%4;jv21fv@KvIc*{#2NH3Nzr#sC~)W0H9W=>CjJ65 zcb~ipRkZ8}>$1VqAgb)uNJGV$(}N-~P^Q$QLIjdf`JVxy&|bH_ylDGj|8S(!Ip`~c)}*3qpe7{Ns7;% z5OPQ258Fn&k}cm!>i&cttF?{fxpZ%ny8?Z>2RXL#LRE4?w$|)nEp?~1w2bQMvQzhD z)C}TxmK6Kw!u+XUSz@WMKvsPvFr}>V&G?PQW)ac z6CYi}rC0*)*tQb23Sm-|4^8f4cyj6)UY|U`$mY~Oa?fzRjgjR&;7yKWG(V0(ycOdO zwX}IM#&hDtP70!r^F|62l=U)*Jf?6ncJxPL=)h)w!N38m&Fnk-n4a3hO!hqvdwBnM zETnLN;^sbw9?k7uJ8GW-F?`7-a@mahvF~u{XIE@{u>QsL;CL`8j;b zRf=oop7ZB1&KI#qcVjt_rAOH>WAl^0;rbrFZd=Rn4sef&UyLp3v{NIoB=BvFCtm`T Cd@0lb literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java new file mode 100644 index 0000000..c14eca7 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/gcat/GCatCaller.java @@ -0,0 +1,69 @@ +package org.gcube.datacatalogue.ckanutillibrary.gcat; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.List; + +import org.gcube.datacatalogue.ckanutillibrary.ckan.SimpleExtendCkanClient; +import org.gcube.gcat.client.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import eu.trentorise.opendata.jackan.model.CkanDataset; +import eu.trentorise.opendata.jackan.model.CkanLicense; + +// TODO: Auto-generated Javadoc +/** + * The Class GCatCaller. + * + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) + * May 29, 2020 + */ +public class GCatCaller { + + private SimpleExtendCkanClient jackanCkanClient; + + private String catalogueURL; + + private static final Logger LOG = LoggerFactory.getLogger(GCatCaller.class); + + /** + * Instantiates a new g cat caller. + */ + public GCatCaller(String catalogueURL) { + this.catalogueURL = catalogueURL; + this.jackanCkanClient = new SimpleExtendCkanClient(catalogueURL); + } + + + /** + * Gets the dataset for name. + * + * @param datasetIdOrName the dataset id or name + * @return the dataset for name + * @throws JsonParseException the json parse exception + * @throws JsonMappingException the json mapping exception + * @throws IOException Signals that an I/O exception has occurred. + */ + public CkanDataset getDatasetForName(String datasetIdOrName) throws JsonParseException, JsonMappingException, IOException { + LOG.debug("Get dataset for name "+datasetIdOrName+ "called"); + String json = new Item().read(datasetIdOrName); + return SimpleExtendCkanClient.getObjectMapper().readValue(json, CkanDataset.class); + } + + + /** + * TODO gCAT missing + * @return + * @throws MalformedURLException + */ + + public List getLicenseList() { + LOG.debug("Get linces list called"); + return jackanCkanClient.getLicenseList(); + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/ApplicationProfileScopePerUrlReader.class new file mode 100644 index 0000000000000000000000000000000000000000..63cb4e9ebf468af621c9d0ea4799f19ad74fb55a GIT binary patch literal 5309 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 client = client(); + List appProfile = client.submit(q); + + if (appProfile == null || appProfile.size() == 0) + throw new ApplicationProfileNotFoundException("Your applicationProfile is not registered in the infrastructure"); + else{ + 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); + + List urls = helper.evaluate("/Resource/Profile/Body/EndPoint/URL/text()"); + if (urls != null && urls.size() > 0) { + boolean foundScope = false; + for (int i = 0; i < urls.size(); i++) { + if (urls.get(i).trim().compareTo(url) == 0) { // url found + scopeToReturn = helper.evaluate("/Resource/Profile/Body/EndPoint/Scope/text()").get(i); + logger.debug("Found, returning " + scopeToReturn); + foundScope = true; + break; + } + } + if (!foundScope || scopeToReturn == null || scopeToReturn.isEmpty()){ + logger.debug("Scope is missing for url " + url + ". Returning " + scope); + } + } + else + throw + new ApplicationProfileNotFoundException("Your applicationProfile EndPoint was not found in the profile, consider adding element in "); + } + } catch (Exception e) { + logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e); + }finally{ + ScopeProvider.instance.set(scope); + } + + return scopeToReturn; + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.class new file mode 100644 index 0000000000000000000000000000000000000000..fd892068ecf947dad6c9ede7108adbaa6c51c85a GIT binary patch literal 895 zcmbtR!EVz)5Pj=74hg2Ap-rJsnjj%1Myd}SsUnq19NMTH8b#u`c2{Ow$F4T(O8qD# zDp6JHfe+xL5VLF3P+CqLyfZuVcHW!kA3v|Z19*#m0}jJ>u97f`i%5h=T=ST|G*1c< z#wR>0v`kYODXz}Lxlm_9g}eJZ2b26nWbXyf8gLmNAM-OFraVi+kI}J+HG{`b<-Ry) z=!_T5L#sPlX}F^9o&WQ4W|t5Zhj1CYBg#gWtv%Q?en{6FiPT@s;ps%2LO z!@K$kGG9Pe@7d5S=+l_V!WCMNeDUewA4PXyy=Wcgg^I-oX?MHzJGPA3=#v{Y`oj)f zV-97mv4&!uI!(0bd`P!XgmNjigDd#Kn@dW1msq}_l7lC7c5Hi%&ZqS38J4h)6{`2_ z_%>G2r5g>fG|Xm($RUC?dQ;Mb6iu%ld_(&yCFO9>7B}obzXVhR8BwiM#b_K6+M(!K zeG6$VTkR9^D?6cEqHZL4l_ZAecu~y?3G-XX@|VAayuMe+243C>soAZ)VDpworH~=f P1^*CY95D`TTE^ZlNoAhp literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java new file mode 100644 index 0000000..9cd9ba5 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/CKANTokenBean.java @@ -0,0 +1,44 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + + +// TODO: Auto-generated Javadoc +/** + * The Class CKANTokenBean. + * + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) + * Jun 1, 2020 + */ +public class CKANTokenBean { + + protected String apiKey; + protected long timestamp; + + /** + * Instantiates a new CKAN token bean. + * + * @param apiKey the api key + * @param timestamp the timestamp + */ + public CKANTokenBean(String apiKey, long timestamp) { + super(); + this.apiKey = apiKey; + this.timestamp = timestamp; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.class new file mode 100644 index 0000000000000000000000000000000000000000..dc5abafb4ec11370216accfc506457120562f55b GIT binary patch literal 2450 zcmdT`OHHfN>dp>>r@DTtW!%`pgFjx+i@Az(9L&xKqyYvO2 zAEV>G<1*GF2t-YB)pR0MN2r{qBv5V(^+7L#kwbpOoq$W zuhdL_cZ3d*!9t;OqOz@(kbZHolf_`pN4+aix~kdG=0(RA(i^;yCGGZp zE^q^@$1XOs2xZgkV`U`pQh;s*Y3fl3cc9Xr)zcoyZJ~6LLFE`WJ$^d;*>=!YH{pxs`Q8-yYH>w(K8F$^QbY0*Y=491C0C5bZulh)Q$ zvR;AdRAYwrufl9fUnBZ@hQ2}cO}J(CZ^IqC-c9JaWSxhFRR12y7c%rB(f8p2dCTCT H_4&~^RLm63 literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java new file mode 100644 index 0000000..800a459 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogue.java @@ -0,0 +1,200 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import java.util.List; +import java.util.Map; + +import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; + +import eu.trentorise.opendata.jackan.model.CkanDataset; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanLicense; +import eu.trentorise.opendata.jackan.model.CkanOrganization; + +public interface DataCatalogue { + + /** + * Finds the id associated to the chosen license + * + * @param chosenLicense + * @return the id on success, null otherwise + */ + String findLicenseIdByLicenseTitle(String chosenLicense); + + /** + * Given the id or the name of the dataset it returns its current url by + * contacting the uri resolver. If no uri resolver is available, an url that is + * not guaranteed to be long term valid will be generated. Information are not + * encrypted. + * + * @param datasetId + * @return The url of the dataset on success, null otherwise + */ + String getUnencryptedUrlFromDatasetIdOrName(String datasetIdOrName); + + /** + * Create a dataset with those information. The method allows to have multiple + * values for the same custom field key. NOTE: unfortunately java doesn't + * support overload in java interface methods (that's way I cannot use the same + * name for the method) + * + * @param title + * @param name (unique identifier) + * @param organizationNameOrId + * @param author + * @param authorMail + * @param maintainer + * @param maintainerMail + * @param version + * @param description + * @param licenseId + * @param tags + * @param customFields + * @param resources + * @param setPublic (manage visibility: Admin role is needed) + * @return the id of the dataset on success, null otherwise + * @throws Exception + */ + String createCKanDatasetMultipleCustomFields(String title, String name, String organizationNameOrId, String author, + String authorMail, String maintainer, String maintainerMail, long version, String description, + String licenseId, List tags, Map> customFields, List resources, + boolean setPublic) throws Exception; + + /** + * Patch a product with product id productId by using the couples in + * customFieldsToChange. NOTE: only the specified custom fields will be changed. + * If a custom field with a given key already exists, and removeOld is set to + * false, the new values are added at the end of the list. Otherwise they are + * lost. + * + * @param productId + * @param customFieldsToChange + * @param removeOld + * @return + */ + boolean patchProductCustomFields(String productId, Map> customFieldsToChange, + boolean removeOld); + + /** + * Add a resource described by the bean to the dataset id into + * resource.datasetId + * + * @param resource + * @return String the id of the resource on success, null otherwise + */ + String addResourceToDataset(ResourceBean resource) throws Exception; + + /** + * Remove the resource with id resourceId from the dataset in which it is. + * + * @param resourceId + * @return true on success, false otherwise. + */ + boolean deleteResourceFromDataset(String resourceId); + + /** + * Create a dataset with those information. + * + * @param apiKey + * @param title + * @param name (unique identifier) + * @param organizationNameOrId + * @param author + * @param authorMail + * @param maintainer + * @param maintainerMail + * @param version + * @param description + * @param licenseId + * @param tags + * @param customFields + * @param resources + * @param setPublic (manage visibility: Admin role is needed) + * @return the id of the dataset on success, null otherwise + * @throws Exception + */ + + /** + * Checks if a product with such name already exists. Please remember that the + * name is unique. + * + * @param nameOrId the name or the id of the dataset to check + * @return + */ + boolean existProductWithNameOrId(String nameOrId); + + /** + * The method returns the role the user has in the groups he/she belongs to (it + * uses the db, so it is much faster) + * + * @param username + * @param apiKey + * @return + */ + Map> getUserRoleByGroup(String username, String apiKey); + + /** + * Get the list of licenses' titles. + * + * @return the list of licenses' titles + */ + List getLicenseTitles(); + + /** + * Retrieve ckan licenses + * + * @return + */ + List getLicenses(); + + /** + * Retrieve the url of the uri resolver for this catalogue instance/scope + * + * @return + */ + String getUriResolverUrl(); + + /** + * Return the manage product property + * + * @return the manage product property + */ + boolean isManageProductEnabled(); + + /** + * Return the catalogue portlet for this context(i.e. scope) + * + * @return + */ + String getPortletUrl(); + + /** + * Return the ckan catalogue url in this scope. + * + * @return the catalogue url + */ + String getCatalogueUrl(); + + + /** + * Returns the list of organizations to whom the user belongs (with any role) + * @param username + * @return a list of organizations + */ + List getOrganizationsByUser(String username); + + /** + * Returns the list of groups to whom the user belongs (with any role) + * @param username + * @return a list of groups + */ + List getGroupsByUser(String username); + + /** + * Retrieve a ckan dataset given its id + * @param datasetId + * @return + */ + CkanDataset getDataset(String datasetId, String apiKey); + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory$CacheBean.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueFactory$CacheBean.class new file mode 100644 index 0000000000000000000000000000000000000000..e346cc48fedac72cc61a645fd2808338bc085d05 GIT binary patch literal 927 zcmb_aO)mpM7=GUEw$)lxDe7C|KqXehrCScKD9cinD~`O>`>sR($fxSL5gxD!#9hDwFL z7W&Ceq<)mzJ>UWFd+106X{?`CJrUfr zj_)7T4xx~yia;lXQhF06t6PM_T)2a8Fm!1*jKXw}@Vxdfh$p#F`u|<;5Nt2LmK6}j z98^%PqJVJ+!>F?uYwI0zGU=d? zXh=BE_0nHPU@fZ`ai#-#6dLO0U%uHiMj<%IQ6#meM3Ts)j3t7X$0dWe5Gp^m#4_tr zVAq?);&6nK3#iqMpxm*cSWt)K2zOUJS>)VkZS*kOdPS|Z+`~kxY4^~0;R6fP9P6+- tPBX*|M$yD1X1M~>8KMU7%yKrBA+!3Gp|`o7`TO7Beh2V6eu$t+ zAXRh=iGu0pWFl{PhRKgzEch~EUNs!wvuxYSxrV!*C`)%ux`{J9ka~1z!Z5v}yBP3cdxqm>4cnKkgbD1sJ|Ymc0=X###sggqBBuFP(=eB*uQw9_SFR?^qGS55D;+OE zB;oR$QC^-hO1#oGYZV;B^Icy1@j0&zSI-4;ne|-DDI{Nn1BX%y{g^bIakU1UQ*h|L>(yQ_!a5xM|fH-9v<#Mv`Y5LkA z@RE*JY|*&duj3VTk?`RFgxWlyL&sKuZ5hjv7yQ+nbmxqm&B!qsOvBC^uBDy>p@wGc zkK%|xcZz8jU#jL+yci@>Jm*_>z8$^jkD!m4_M|g91~5oQ^D^fb1a{VY5XQVO8^KY5 zBhSaRh9T@%Uc9EG1KSu*Z`mpfXpB=BIf1ji)wnd8ic!2N&>5!lb#pwu`V|BG&jjxUo zj0!}o^7v}WTMx2uA%c`ZPfbzUwq?PvN8N(I$`aeu8^yT5j~k+hCUoEKpB<#eW0mqTRg}_=;zN?0a;4$1x5ZQEM=!)P>9KfVKE70RLqaty;H>)kScice zdxcRdNr!#$UFXtA87Vgy$O zMj9bk1w_M&a>YR@g5u-Fu+GX|)o~3RdY$3?n6p;pl$xVtgUxwTBTJr2YM)c&g(N|8 zvT>68vZ`dR>$m|`z9pX}bF!Y9us-Ud{QpJ7^b5*ZHT$Pn;h3N0i^f&X)S&sRto=gA zmx$7?=h+-b!Dv>)O<=kq*PgBtwz}D(@0xPLQp2eGS?@DP6=uGmq#Z}P!3dP(u5EMV z;s7hUneQeo*sDe$S9=jbl+re?o1pQZ(~oOS%@4}A2l7syjv|IGN_J3^D8+9CitiwPJAk18 zYQg>>e}^`~3A}}ql)ugW7V3E?@b@1&q2lHb`~_{`K89~%>juW=V`nOu_~QaLl_{ucEa095{_XQr*IlsPO(LdqRg?Qq8zV+4MRfM_ynKQnMJ-= zvB}cC&v>d8&FyWyd|-nQBQ`^y6|-Ff_we}+Xa;fo^b1;BZZ+ScxQb#64+ELN(yr?9 iO-o()3SV2HSU cache; + + private class CacheBean{ + DataCatalogueImpl utils; + long ttl; + + public CacheBean(long ttl, DataCatalogueImpl utils){ + this.ttl = ttl; + this.utils = utils; + } + } + + /** + * Private constructor + */ + private DataCatalogueFactory(){ + + logger.debug("Ckan factory object build"); + cache = new ConcurrentHashMap(); + + } + + /** + * Get the factory instance + * @return + */ + public static DataCatalogueFactory getFactory(){ + logger.debug("Factory requested"); + return instance; + } + + /** + * Retrieve the ckan utils information for the given scope + * @param scope + * @return + * @throws Exception + */ + public DataCatalogueImpl getUtilsPerScope(String scope) throws Exception{ + + if(scope == null || scope.isEmpty()) + throw new IllegalArgumentException("Invalid scope given!"); + + if(cache.containsKey(scope) && !expired(cache.get(scope))){ + return cache.get(scope).utils; + } + else{ + logger.info("Creating CKAN LIB utils for scope " + scope); + DataCatalogueImpl utils = new DataCatalogueImpl(scope); + cache.put(scope, new CacheBean(System.currentTimeMillis(), utils)); + return utils; + } + } + + /** + * Check if the ckan information must be retrieved again. + * @param cacheBean + * @return + */ + private boolean expired(CacheBean cacheBean) { + return (cacheBean.ttl + MAX_LIFETIME < System.currentTimeMillis()); + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..80c093aaf587cada7799c7049c06f52f61597078 GIT binary patch literal 20700 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 literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java new file mode 100644 index 0000000..c2f2839 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueImpl.java @@ -0,0 +1,543 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.gcube.common.scope.impl.ScopeBean.Type; +import org.gcube.datacatalogue.ckanutillibrary.ckan.ExtendCkanClient; +import org.gcube.datacatalogue.ckanutillibrary.ckan.SimpleExtendCkanClient; +import org.gcube.datacatalogue.ckanutillibrary.db.DBCaller; +import org.gcube.datacatalogue.ckanutillibrary.gcat.GCatCaller; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.CatalogueUtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.url.EntityContext; +import org.gcube.datacatalogue.ckanutillibrary.shared.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; +import org.gcube.datacatalogue.ckanutillibrary.shared.State; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import eu.trentorise.opendata.jackan.internal.org.apache.http.HttpResponse; +import eu.trentorise.opendata.jackan.internal.org.apache.http.client.methods.HttpPost; +import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.ContentType; +import eu.trentorise.opendata.jackan.internal.org.apache.http.entity.StringEntity; +import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.CloseableHttpClient; +import eu.trentorise.opendata.jackan.internal.org.apache.http.impl.client.HttpClientBuilder; +import eu.trentorise.opendata.jackan.internal.org.apache.http.util.EntityUtils; +import eu.trentorise.opendata.jackan.model.CkanDataset; +import eu.trentorise.opendata.jackan.model.CkanGroup; +import eu.trentorise.opendata.jackan.model.CkanLicense; +import eu.trentorise.opendata.jackan.model.CkanOrganization; +import eu.trentorise.opendata.jackan.model.CkanUser; + +public class DataCatalogueImpl implements DataCatalogue { + + private static final Logger LOG = LoggerFactory.getLogger(DataCatalogueImpl.class); + + private String CKAN_CATALOGUE_URL; + private String CKAN_DB_NAME; + private String CKAN_DB_USER; + private String CKAN_DB_PASSWORD; + private String CKAN_DB_URL; + private Integer CKAN_DB_PORT; + private String PORTLET_URL_FOR_SCOPE; + private String SOLR_URL; + private String CKAN_TOKEN_SYS; + private String CKAN_EMAIL; + private String URI_RESOLVER_URL; + private boolean MANAGE_PRODUCT_BUTTON; + private boolean SOCIAL_POST; + private boolean ALERT_USERS_ON_POST_CREATION; + private String CONTEXT; + private Map extendRoleInOrganization; + + public Map mapAccessURLToCatalogue; + + private static final String CATALOGUE_TAB_ENDING_URL = "/catalogue"; + + // gCat client + private GCatCaller gCatCaller; + + // db client + private DBCaller dbCaller; + + // ckan client + private SimpleExtendCkanClient ckanCaller; + + // hashmap for ckan api keys + private ConcurrentHashMap apiKeysMap; + + // apikey bean expires after X minutes in the above map + private static final int EXPIRE_KEY_TIME = 60 * 60 * 1000; + + + /** + * The ckan catalogue url and database will be discovered in this scope + * @param scope + * @throws Exception if unable to find datacatalogue info + */ + public DataCatalogueImpl(String scope) throws Exception{ + + DataCatalogueRunningCluster runningInstance = new DataCatalogueRunningCluster(scope); + + // save information + CKAN_DB_URL = runningInstance.getDatabaseHosts().get(0).trim(); + CKAN_DB_PORT = runningInstance.getDatabasePorts().get(0); + CKAN_DB_NAME = runningInstance.getDataBaseName().trim(); + CKAN_DB_USER = runningInstance.getDataBaseUser().trim(); + CKAN_DB_PASSWORD = runningInstance.getDataBasePassword().trim(); + + //CKAN_TOKEN_SYS = runningInstance.getSysAdminToken().trim(); + CKAN_EMAIL = runningInstance.getEmailCatalogue().trim(); + + CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0).trim(); + PORTLET_URL_FOR_SCOPE = runningInstance.getPortletUrl().trim(); + mapAccessURLToCatalogue = runningInstance.getMapAccessURLToCatalogue(); + MANAGE_PRODUCT_BUTTON = runningInstance.isManageProductEnabled(); + URI_RESOLVER_URL = runningInstance.getUrlResolver(); + SOCIAL_POST = runningInstance.isSocialPostEnabled(); + ALERT_USERS_ON_POST_CREATION = runningInstance.isAlertEnabled(); + SOLR_URL = runningInstance.getUrlSolr(); + + LOG.info("In the scope: "+scope+", I read the catalogue URL: " + CKAN_CATALOGUE_URL); + + // build the clients + gCatCaller = new GCatCaller(CKAN_CATALOGUE_URL); + + dbCaller = new DBCaller(CKAN_DB_URL, CKAN_DB_PORT, CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD); + + ckanCaller = new SimpleExtendCkanClient(CKAN_CATALOGUE_URL); + + // init map + apiKeysMap = new ConcurrentHashMap(); + + // save the context + CONTEXT = scope; + + // extended roles + extendRoleInOrganization = runningInstance.getExtendRoleInOrganization(); + } + + @Override + public String getCatalogueUrl() { + return CKAN_CATALOGUE_URL; + } + + + @Override + public String getPortletUrl() { + + //PATCHED By Francesco + ScopeBean context = new ScopeBean(CONTEXT); + + if(context.is(Type.INFRASTRUCTURE)) { + LOG.info("Working with the {} scope returning the path read from GR 'Ckan-Porltet': {}", Type.INFRASTRUCTURE.toString(), PORTLET_URL_FOR_SCOPE); + return PORTLET_URL_FOR_SCOPE; + } + + String vreNameLower = context.name().toLowerCase(); + //CHECKING IF THE PORTLET URL CONTAINS THE VRE NAME INTO URL + if(PORTLET_URL_FOR_SCOPE.toLowerCase().contains(vreNameLower)){ + //THE PORLTET URL READ FROM GENERIC RESOUCE 'CkanPortlet' SHOULD BE ALREADY VALID, POITING TO CKAN PORTLET + return PORTLET_URL_FOR_SCOPE; + }else{ + //ADDING VRE getApiKeyFromUsernameNAME AND THE SUFFIX 'CATALOGUE_TAB_ENDING_URL' TO URL + String buildedUrl = PORTLET_URL_FOR_SCOPE.endsWith("/") ? PORTLET_URL_FOR_SCOPE : PORTLET_URL_FOR_SCOPE + "/"; + String defaultSuffix = vreNameLower + CATALOGUE_TAB_ENDING_URL; + buildedUrl+= defaultSuffix; + LOG.warn("The Portlet URL read from Generic Resource 'Ckan-Porltet' does not contain the portlet suffix, so I added the default: "+defaultSuffix); + return buildedUrl; + } + } + + + @Override + public String findLicenseIdByLicenseTitle(String chosenLicense) { + LOG.debug("Requested license id"); + + // checks + checkNotNull(chosenLicense); + + //retrieve the list of available licenses + List licenses = ckanCaller.getLicenseList(); + + for (CkanLicense ckanLicense : licenses) { + if(ckanLicense.getTitle().equals(chosenLicense)) + return ckanLicense.getId(); + } + + return null; + } + + @Override + public List getLicenseTitles() { + + LOG.debug("Request for CKAN licenses"); + + // get the url and the api key of the user + List result = new ArrayList(); + + //retrieve the list of available licenses + List licenses = ckanCaller.getLicenseList(); + + for (CkanLicense ckanLicense : licenses) { + + result.add(ckanLicense.getTitle()); + LOG.debug("License is " + ckanLicense.getTitle() + " and id " + ckanLicense.getId()); + + } + + return result; + } + + @Override + public List getLicenses() { + LOG.debug("Request for CKAN licenses (original jackan objects are going to be retrieved)"); + + //retrieve the list of available licenses + return ckanCaller.getLicenseList(); + } + + @Override + public CkanDataset getDataset(String datasetId, String apiKey) { + + LOG.info("Request ckan dataset with id " + datasetId); + + // checks + checkNotNull(datasetId); + checkArgument(!datasetId.isEmpty()); + + try{ + + if(apiKey!=null && !apiKey.isEmpty()) { + LOG.info("API-KEY found. Calling the "+ExtendCkanClient.class.getSimpleName()); + ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, apiKey); + return client.getDataset(datasetId); + } + + String authzToken = SecurityTokenProvider.instance.get(); + if(authzToken!=null && !authzToken.isEmpty()) { + LOG.info("gcube-token found. Calling the gCat client"); + return gCatCaller.getDatasetForName(datasetId); + } + + LOG.info("No api-key or gcube-token found. Calling Ckan Client without API-KEY"); + return ckanCaller.getDataset(datasetId); + + }catch(Exception e){ + LOG.error("Unable to retrieve such dataset, returning null ...", e); + } + + return null; + } + + + @Override + public String getUnencryptedUrlFromDatasetIdOrName(String datasetIdOrName) { + LOG.debug("Request coming for getting dataset url (not encrypted) of dataset with name/id " + datasetIdOrName); + + // checks + checkNotNull(datasetIdOrName); + checkArgument(!datasetIdOrName.isEmpty()); + String url = null; + try{ + + // get the dataset from name + ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS); + CkanDataset dataset = client.getDataset(datasetIdOrName); + String name = dataset.getName(); + + if(dataset != null){ + + if(getUriResolverUrl() != null) + url = getUrlForProduct(CONTEXT, EntityContext.DATASET, name); + + if(url == null || url.isEmpty()) + url = getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + name, "UTF-8"); + + } + }catch(Exception e){ + LOG.error("Error while retrieving dataset with id/name=" + datasetIdOrName, e); + } //requestEntity.put("clear_url", Boolean.toString(unencrypted)); + return url; + } + + public String createCKanDatasetMultipleCustomFields(String title, String name, String organizationNameOrId, + String author, String authorMail, String maintainer, String maintainerMail, long version, + String description, String licenseId, List tags, Map> customFields, + List resources, boolean setPublic) throws Exception { + return null; + } + + @Override + public Map> getUserRoleByGroup( + String username, String apiKey) { + + checkNotNull(username); + checkNotNull(apiKey); + + checkNotNull(username); + checkNotNull(apiKey); + + Map> toReturn = new HashMap>(); + + try{ + + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + Map partialResult = dbCaller.getGroupsByUserFromDB(ckanUsername); + + for (String groupID : partialResult.keySet()) { + + CkanGroup group = ckanCaller.getGroup(groupID); + HashMap subMap = new HashMap(); + subMap.put(group, partialResult.get(groupID)); + toReturn.put(groupID, subMap); + } + + LOG.debug("Returning map " + toReturn); + }catch(Exception e){ + LOG.error("Failed to retrieve roles of user in his/her own groups",e); + } + + return toReturn; + + } + + + /** + * Retrieve an url for the tuple scope, entity, entity name + * @param context + * @param entityContext + * @param entityName + */ + private String getUrlForProduct(String context, EntityContext entityContext, String entityName){ + + String toReturn = null; + + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { + + HttpPost httpPostRequest = new HttpPost(getUriResolverUrl()); + + JSONObject requestEntity = new JSONObject(); + requestEntity.put("gcube_scope", context); + requestEntity.put("entity_context", entityContext.toString()); + requestEntity.put("entity_name", entityName); + + StringEntity params = new StringEntity(requestEntity.toJSONString(), ContentType.APPLICATION_JSON); + httpPostRequest.setEntity(params); + + HttpResponse response = httpClient.execute(httpPostRequest); + + if(response.getStatusLine().getStatusCode() != 200) + throw new Exception("There was an error while creating an url " + response.getStatusLine()); + + toReturn = EntityUtils.toString(response.getEntity()); + LOG.debug("Result is " + toReturn); + + }catch(Exception e){ + LOG.error("Failed to get an url for this product", e); + } + + return toReturn; + } + + + + @Override + public String getUriResolverUrl() { + return URI_RESOLVER_URL; + } + + /** + * Check if the manage product is enabled + * @return + */ + @Override + public boolean isManageProductEnabled() { + return MANAGE_PRODUCT_BUTTON; + } + + @Override + public List getOrganizationsByUser(String username) { + + LOG.debug("Requested organizations for user " + username); + + // checks + checkNotNull(username); + + // in order to avoid errors, the username is always converted + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + + // list to return + List toReturn = new ArrayList(); + + try{ + + // get the list of all organizations + List organizations = ckanCaller.getOrganizationList(); + + // iterate over them + for (CkanOrganization ckanOrganization : organizations) { + + // get the list of users in it (if you try ckanOrganization.getUsers() it returns null.. maybe a bug TODO) + List users = ckanCaller.getOrganization(ckanOrganization.getName()).getUsers(); + + // check if the current user is among them + for (CkanUser ckanUser : users) { + if(ckanUser.getName().equals(ckanUsername)){ + + LOG.debug("User " + ckanUsername + " is into " + ckanOrganization.getName()); + toReturn.add(ckanOrganization); + break; + + } + } + } + }catch(Exception e){ + LOG.error("Unable to get user's organizations", e); + } + return toReturn; + } + + @Override + public List getGroupsByUser(String username) { + LOG.debug("Requested groups for user " + username); + + // checks + checkNotNull(username); + + // in order to avoid errors, the username is always converted + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + + // list to return + List toReturn = new ArrayList(); + + try{ + + // get the list of all organizations + List groups = ckanCaller.getGroupList(); + + // iterate over them + for (CkanGroup ckanGroup : groups) { + + List users = ckanCaller.getGroup(ckanGroup.getName()).getUsers(); + + // check if the current user is among them + for (CkanUser ckanUser : users) { + if(ckanUser.getName().equals(ckanUsername)){ + + LOG.debug("User " + ckanUsername + " is into " + ckanGroup.getName()); + toReturn.add(ckanGroup); + break; + + } + } + } + }catch(Exception e){ + LOG.error("Unable to get user's groups", e); + } + return toReturn; + } + + //@Override + private String getApiKeyFromUsername(String username) { + + LOG.debug("Request api key for user = " + username); + + // checks + checkNotNull(username); + checkArgument(!username.isEmpty()); + + // in order to avoid errors, the username is always converted + String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); + + // check in the hashmap first + if(apiKeysMap.containsKey(ckanUsername)){ + CKANTokenBean bean = apiKeysMap.get(ckanUsername); + if(bean.timestamp + EXPIRE_KEY_TIME > System.currentTimeMillis()){ // it's still ok + return bean.apiKey; + } + } + + LOG.debug("Api key was not in cache or it expired"); + + try{ + + String apiToReturn = dbCaller.getApiKeyFromUsername(username, State.ACTIVE.name().toLowerCase()); + + // save into the hashmap + if(apiToReturn != null) + apiKeysMap.put(ckanUsername, new CKANTokenBean(apiToReturn, System.currentTimeMillis())); + + return apiToReturn; + + }catch(Exception e){ + LOG.error("Unable to retrieve key for user " + ckanUsername, e); + } + + return null; + } + + + + + + + + + + + + /* + * + * + * + * + * + * + * + * + * + * WRITE OPERATIONS + * + * + * + * + * + * + * + * + * + * + */ + + + public boolean patchProductCustomFields(String productId, Map> customFieldsToChange, + boolean removeOld) { + return false; + } + + public String addResourceToDataset(ResourceBean resource) throws Exception { + return null; + } + + public boolean deleteResourceFromDataset(String resourceId) { + return false; + } + + public boolean existProductWithNameOrId(String nameOrId) { + return false; + } + + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster$ACCESS_LEVEL_TO_CATALOGUE_PORTLET.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster$ACCESS_LEVEL_TO_CATALOGUE_PORTLET.class new file mode 100644 index 0000000000000000000000000000000000000000..91d0aee89d019c8d888c412f48c596db7800b699 GIT binary patch literal 1718 zcmcgt-%ry}6#lN=Zz|x>=>QcJbsNY;g%=jWtd&d)BkMM^_^{lSI*X;lZY9~9@h{Tx z0MST%_Kz~2TLSEJi_Cwi+&XyVebntLC+esx!1+4O?0yXV{iwb=DZ9RJzI#P+B`?1i=^> z#${YWoFSC!QxYld++Drn(#u&bq^nWlUX~F=D1xv6S7n3+hzKw#BZ82)nwAkojA2Z( z9CORtYnX1CH*Aw3uC)wqSGj8m><43zFiv_pZ>%;+IN-Kt(#5+}ddMclFo(Ng+#x>( zn(xw<+>>z+DTXL_UEVcX`(1|2phd;Tu4!~u3j?m5hR8OCu-{ejHN%I&w7#?H;cf4+Dr|T`xHOyz0c&Rgg8RkWiO3vw4)8QS@CHnh; zCx~*n;kLg<^5uf#n6BTi*$(3|!}I@lR4~l`^8{O8qA`)^{0yuo#XJGD(kS^WO%X6Y zDP~A8XsSja6aOM1PFQ^MU%+bdQRxU{hnVoem4FWtKDZY2K{E7}cv24&dM(gHLazmT zNa}}}`b0%8;5z+=s5G#T8-7GY=`iR&Ziz$+nc>X*^bv0UK1paJ3TA|EQay`X{qz;; zO{6D!n5w;yGAFg1(6cE`9pm=GN4hg8ft^W+((cUkYh;Kc>c`?NbBy_KV1Le&u;|y! T;(@;|;i1T+d`ACN%j?OX!OYC5 literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.class new file mode 100644 index 0000000000000000000000000000000000000000..15a2ffdfae6aff04b3ef2e8bd1bf4a8342f71b7c GIT binary patch literal 18230 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 SGoI7%+yZQU0s|#32>cIPxR$&C literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java new file mode 100644 index 0000000..3f153ea --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/DataCatalogueRunningCluster.java @@ -0,0 +1,690 @@ +package org.gcube.datacatalogue.ckanutillibrary.server; + +import static org.gcube.resources.discovery.icclient.ICFactory.client; +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.gcube.common.encryption.StringEncrypter; +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.resources.gcore.utils.XPathHelper; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ApplicationProfileNotFoundException; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.NoApplicationProfileMasterException; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.NoDataCatalogueRuntimeResourceException; +import org.gcube.datacatalogue.ckanutillibrary.shared.ex.ServiceEndPointException; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.Query; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.gcube.resources.discovery.client.queries.impl.QueryBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Retrieve ckan running instance information in the infrastructure (for both its database and data catalogue url). + * + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + * updated by Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + */ +public class DataCatalogueRunningCluster { + + //logger + private static final Logger logger = LoggerFactory.getLogger(DataCatalogueRunningCluster.class); + + // database of the datacatalogue info + private final static String RUNTIME_DB_RESOURCE_NAME = "CKanDatabase"; + private final static String PLATFORM_DB_NAME = "postgres"; + private final static String APPLICATION_PROFILE_NAME = "CkanPortlet"; + + // data catalogue info + private final static String RUNTIME_CATALOGUE_RESOURCE_NAME = "CKanDataCatalogue"; + private final static String PLATFORM_CATALOGUE_NAME = "Tomcat"; + + // api key property for SYSADMIN + private final static String API_KEY_PROPERTY = "API_KEY"; + + // catalogue email + private final static String CKAN_EMAIL_PROPERTY = "CATALOGUE_EMAIL"; + + // 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 IS_MANAGE_PRODUCT_ENABLED = "IS_MANAGE_PRODUCT_ENABLED"; // true, false.. missing means false as well (for GRSF records) + + 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 SOLR_INDEX_ADDRESS = "SOLR_INDEX_ADDRESS"; + + // url of the http uri for this scope + private final static String URL_RESOLVER = "URL_RESOLVER"; + + // Other generic resource for delegating roles in groups to users + private final static String CATALOGUE_EXTENDING_ROLES = "CatalogueDelegateRoles"; + + // retrieved data + private List datacatalogueUrls = new ArrayList(); + private List hostsDB = new ArrayList(); + private List portsDB = new ArrayList(); + private String nameDB; + private String userDB; + private String passwordDB; + private String portletUrl; + private String urlSolr; + private boolean manageProductEnabled; + private String urlResolver; + private boolean socialPost; + private boolean alertUsers; + private Map extendRoleInOrganization = new HashMap(0); + + // generic role key + public static final String CKAN_GENERIC_ROLE = "*"; + public static final String ROLE_ORGANIZATION_SEPARATOR = "|"; + public static final String TUPLES_SEPARATOR = ","; + + private static final String DEFAULT_CATALOGUE_EMAIL = "catalogue@d4science.org"; + + /** + * The Enum ACCESS_LEVEL_TO_CATALOGUE_PORTLET. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * + * Nov 12, 2019 + */ + //Added by Francesco, see #18039 + public static final String PUBLIC_VRE_CATALOGUE_URL = "public-vre-url"; + public static enum ACCESS_LEVEL_TO_CATALOGUE_PORTLET {PUBLIC_GATEWAY, PUBLIC_VRE, PRIVATE_VRE}; + public Map mapAccessURLToCatalogue; + + // this token is needed in order to assign roles to user + private String sysAdminToken; + + private String catalogueEmail; + + /** + * Instantiates a new data catalogue running cluster. + * + * @param scope the scope + * @throws Exception the exception + */ + public DataCatalogueRunningCluster(String scope) throws Exception{ + + if(scope == null || scope.isEmpty()) + throw new Exception("Invalid scope!!"); + + // retrieve the current scope and save it (it will be reset later) + String currentScope = ScopeProvider.instance.get(); + + logger.info("Retrieving ckan database service end point information for scope " + scope); + try { + + // set the scope + ScopeProvider.instance.set(scope); + + logger.debug("Retrieving database information."); + + List resources = getConfigurationFromISFORDB(); + evaluateRightConfigurationDB(resources); + + logger.debug("Retrieving ckan data catalogue service end point information and sysadmin token."); + + resources = getConfigurationFromISFORCatalogueUrl(); + evaluateRightConfigurationCatalogue(resources); + + // finally get the url in which the ckan portlet is deployed + + logger.debug("Looking for portlet url in " + ScopeProvider.instance.get() + " scope" ); + + //portletUrl = getPortletUrlFromInfrastrucure(); + mapAccessURLToCatalogue = getPortletUrlFromInfrastrucure(); + portletUrl = mapAccessURLToCatalogue.get(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PRIVATE_VRE); + + // and parse the CatalogueDelegateRole resource, if any, in this context + parseExtendingRoles(); + + }catch(Exception e) { + logger.warn("The following error occurred: " + e.toString()); + throw e; + }finally{ + ScopeProvider.instance.set(currentScope); + } + } + + + /** + * Evaluate the right configuration about ckan. + * + * @param resources the resources + * @throws NoDataCatalogueRuntimeResourceException the no data catalogue runtime resource exception + * @throws ServiceEndPointException the service end point exception + */ + private void evaluateRightConfigurationCatalogue( + List resources) throws NoDataCatalogueRuntimeResourceException, ServiceEndPointException { + if (resources.size() == 0){ + logger.error("There is no Runtime Resource having name " + RUNTIME_CATALOGUE_RESOURCE_NAME +" and Platform " + PLATFORM_CATALOGUE_NAME + " in this scope."); + throw new NoDataCatalogueRuntimeResourceException(); + } + else { + logger.debug(resources.toString()); + try{ + if(resources.size() > 1){ + boolean oneWasMaster = false; + + logger.info("Too many Runtime Resource having name " + RUNTIME_CATALOGUE_RESOURCE_NAME +" in this scope.. Looking for the one that has the property " + IS_MASTER_ROOT_KEY_PROPERTY); + + for (ServiceEndpoint res : resources) { + + Iterator accessPointIterator = res.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 + oneWasMaster = true; + + // add this host + datacatalogueUrls.add(accessPoint.address()); + + // retrieve sys admin token + sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value(); + sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken); + + // retrieve catalogue email + if(accessPoint.propertyMap().containsKey(CKAN_EMAIL_PROPERTY)){ + catalogueEmail = accessPoint.propertyMap().get(CKAN_EMAIL_PROPERTY).value(); + catalogueEmail = StringEncrypter.getEncrypter().decrypt(catalogueEmail); + } + + // retrieve URL_RESOLVER + if(accessPoint.propertyMap().containsKey(URL_RESOLVER)) + urlResolver = accessPoint.propertyMap().get(URL_RESOLVER).value(); + + // break now + break; + } + } + + // if none of them was master, throw an exception + if(!oneWasMaster) + throw new NoApplicationProfileMasterException("There is no application profile with MASTER property"); + + }else{ + + ServiceEndpoint res = resources.get(0); + Iterator accessPointIterator = res.profile().accessPoints().iterator(); + + while (accessPointIterator.hasNext()) { + ServiceEndpoint.AccessPoint accessPoint = accessPointIterator + .next(); + + // add this host + datacatalogueUrls.add(accessPoint.address()); + + // retrieve sys admin token + sysAdminToken = accessPoint.propertyMap().get(API_KEY_PROPERTY).value(); + sysAdminToken = StringEncrypter.getEncrypter().decrypt(sysAdminToken); + + // retrieve catalogue email + if(accessPoint.propertyMap().containsKey(CKAN_EMAIL_PROPERTY)){ + catalogueEmail = accessPoint.propertyMap().get(CKAN_EMAIL_PROPERTY).value(); + catalogueEmail = StringEncrypter.getEncrypter().decrypt(catalogueEmail); + } + + // get the is manage product property + Property entry = accessPoint.propertyMap().get(IS_MANAGE_PRODUCT_ENABLED); + String isManageProduct = entry != null ? entry.value() : null; + + if(isManageProduct != null && isManageProduct.equals("true")){ + logger.info("Manage product is enabled in this scope"); + manageProductEnabled = true; + } + + // retrieve option to check if the social post has to be made + socialPost = true; // default is true + if(accessPoint.propertyMap().containsKey(SOCIAL_POST)) + if(accessPoint.propertyMap().get(SOCIAL_POST).value().trim().equalsIgnoreCase("false")) + socialPost = false; + + + // retrieve option for user alert + if(accessPoint.propertyMap().containsKey(ALERT_USERS_ON_POST_CREATION)) + if(accessPoint.propertyMap().get(ALERT_USERS_ON_POST_CREATION).value().trim().equalsIgnoreCase("true")) + alertUsers = true; + + // retrieve URL_RESOLVER + if(accessPoint.propertyMap().containsKey(URL_RESOLVER)) + urlResolver = accessPoint.propertyMap().get(URL_RESOLVER).value(); + + // retrieve url of the solr index for further queries + if(accessPoint.propertyMap().containsKey(SOLR_INDEX_ADDRESS)) + urlSolr = accessPoint.propertyMap().get(SOLR_INDEX_ADDRESS).value(); + + } + } + + }catch(Exception e){ + throw new ServiceEndPointException("There is no service end point for such information" + e.toString()); + } + } + + + } + + /** + * Retrieve the right DB information. + * + * @param resources the resources + * @throws ServiceEndPointException the service end point exception + * @throws NoDataCatalogueRuntimeResourceException the no data catalogue runtime resource exception + */ + private void evaluateRightConfigurationDB(List resources) throws ServiceEndPointException, NoDataCatalogueRuntimeResourceException { + + if (resources.size() == 0){ + throw new NoDataCatalogueRuntimeResourceException("There is no Runtime Resource having name " + RUNTIME_DB_RESOURCE_NAME +" and Platform " + PLATFORM_DB_NAME + " in this scope."); + } + else { + try{ + + if(resources.size() > 1){ + boolean oneWasMaster = false; + + logger.info("Too many Runtime Resource having name " + RUNTIME_DB_RESOURCE_NAME +" in this scope.. Looking for the one that has the property " + IS_MASTER_ROOT_KEY_PROPERTY); + + for (ServiceEndpoint res : resources) { + + Iterator accessPointIterator = res.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 + oneWasMaster = true; + + // add this host + hostsDB.add(accessPoint.address().split(":")[0]); + + // save the port + int port = Integer.parseInt(accessPoint.address().split(":")[1]); + portsDB.add(port); + + // save the name of the cluster (this should be unique) + nameDB = accessPoint.name(); + + // save user and password + passwordDB = StringEncrypter.getEncrypter().decrypt(accessPoint.password()); + userDB = accessPoint.username(); + + // now break + break; + } + } + + // if none of them was master, throw an exception + if(!oneWasMaster) + throw new NoApplicationProfileMasterException("There is no application profile with MASTER property"); + }else{ + logger.debug(resources.toString()); + ServiceEndpoint res = resources.get(0); + Iterator accessPointIterator = res.profile().accessPoints().iterator(); + + while (accessPointIterator.hasNext()) { + ServiceEndpoint.AccessPoint accessPoint = accessPointIterator + .next(); + + // add this host + hostsDB.add(accessPoint.address().split(":")[0]); + + // save the port + int port = Integer.parseInt(accessPoint.address().split(":")[1]); + portsDB.add(port); + + // save the name of the cluster (this should be unique) + nameDB = accessPoint.name(); + + // save user and password + passwordDB = StringEncrypter.getEncrypter().decrypt(accessPoint.password()); + userDB = accessPoint.username(); + + } + } + }catch(Exception e ){ + throw new ServiceEndPointException(e.toString()); + } + } + } + + /** + * Retrieve endpoints information from IS for DB. + * + * @return list of endpoints for ckan database + * @throws Exception the exception + */ + private static List getConfigurationFromISFORDB() throws Exception{ + + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_DB_RESOURCE_NAME +"'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ PLATFORM_DB_NAME +"'"); + DiscoveryClient client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + return toReturn; + + } + + /** + * Retrieve endpoints information from IS for DataCatalogue URL. + * + * @return list of endpoints for ckan data catalogue + * @throws Exception the exception + */ + private static List getConfigurationFromISFORCatalogueUrl() throws Exception{ + + 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 client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + return toReturn; + + } + + /** + * Retrieve the url of the ckan portlet deployed into this scope + * updated by Francesco see Feature #18039. + * + * @return the portlet url from infrastrucure + */ + private static Map getPortletUrlFromInfrastrucure() { + + String scope = ScopeProvider.instance.get(); + logger.debug("Trying to fetch applicationProfile profile from the infrastructure for " + APPLICATION_PROFILE_NAME + " scope: " + scope); + Map mapAccess = new HashMap(3); + try { + + Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + + " eq '" + APPLICATION_PROFILE_NAME + "'" + + "return $profile"); + + DiscoveryClient client = client(); + List appProfile = client.submit(q); + + if (appProfile == null || appProfile.size() == 0) + throw new ApplicationProfileNotFoundException("Your applicationProfile is not registered in the infrastructure"); + else { + 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); + + List currValue = null; + currValue = helper.evaluate("/Resource/Profile/Body/url/text()"); + if (currValue != null && currValue.size() > 0) { + logger.debug("Private portlet url found is " + currValue.get(0)); + //return currValue.get(0); + mapAccess.put(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PRIVATE_VRE, currValue.get(0)); + } + + currValue = null; + currValue = helper.evaluate("/Resource/Profile/Body/"+PUBLIC_VRE_CATALOGUE_URL+"/text()"); + if (currValue != null && currValue.size() > 0) { + logger.debug(PUBLIC_VRE_CATALOGUE_URL+" portlet url found is " + currValue.get(0)); + //return currValue.get(0); + mapAccess.put(ACCESS_LEVEL_TO_CATALOGUE_PORTLET.PUBLIC_VRE, currValue.get(0)); + } + + } + + } catch (Exception e) { + logger.error("Error while trying to fetch applicationProfile profile from the infrastructure", e); + } + + return mapAccess; + + } + + /** + * Parse the CatalogueDelegateRoles in this context. + * + * @throws ParserConfigurationException the parser configuration exception + * @throws SAXException the SAX exception + * @throws IOException Signals that an I/O exception has occurred. + */ + private void parseExtendingRoles() throws ParserConfigurationException, SAXException, IOException { + + Query q = new QueryBox("for $profile in collection('/db/Profiles/GenericResource')//Resource " + + "where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Name/string() " + + " eq '" + CATALOGUE_EXTENDING_ROLES + "'" + + "return $profile"); + + DiscoveryClient client = client(); + List appProfile = client.submit(q); + + logger.debug("Resource for extending role has size " + appProfile.size()); + + if (appProfile == null || appProfile.size() == 0) + return; + else { + String profile = appProfile.get(0); + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Node node = docBuilder.parse(new InputSource(new StringReader(profile))).getDocumentElement(); + XPathHelper helper = new XPathHelper(node); + + // fetch delegate elements + NodeList delegates = helper.evaluateForNodes("/Resource/Profile/Body/delegates/delegate"); + if (delegates != null && delegates.getLength() > 0) { + + for(int i = 0; i < delegates.getLength(); i++){ + + Node nodeI = delegates.item(i); + + if(nodeI.getNodeType() == Node.ELEMENT_NODE) { + + Element elem = (Element)nodeI; + String role = elem.getElementsByTagName("sourceRole").item(0).getTextContent(); + String destOrg = elem.getElementsByTagName("destOrganization").item(0).getTextContent(); + String sourceOrg = elem.getElementsByTagName("sourceOrganization").item(0).getTextContent(); + + if(destOrg == null || sourceOrg == null){ + logger.warn("DestOrg or SourceOrg parameters missing"); + continue; + }else{ + String currentValueForKey = extendRoleInOrganization.get(sourceOrg); + + if(currentValueForKey == null) + currentValueForKey = ""; + else + currentValueForKey += TUPLES_SEPARATOR; + + currentValueForKey += destOrg + ROLE_ORGANIZATION_SEPARATOR + role; + extendRoleInOrganization.put(sourceOrg, currentValueForKey); + } + } + } + } + + } + + logger.debug("Extended role map in this scope is " + extendRoleInOrganization); + } + + /** + * Retrieve the ckan portlet url. + * + * @return the portletUrl + */ + public String getPortletUrl() { + return portletUrl; + } + + /** + * Retrieve data catalogue url. + * + * @return the data catalogue url + */ + public List getDataCatalogueUrl() { + return datacatalogueUrls; + } + + /** + * Get the hosts for such resource. + * + * @return the database hosts + */ + public List getDatabaseHosts() { + return hostsDB; + } + + /** + * Get the ports for such resource. + * + * @return the database ports + */ + public List getDatabasePorts() { + return portsDB; + } + + /** + * Get the database name. + * + * @return the data base name + */ + public String getDataBaseName() { + return nameDB; + } + + /** + * Get the database's user. + * + * @return the data base user + */ + public String getDataBaseUser() { + return userDB; + } + + /** + * Get the database's password. + * + * @return the data base password + */ + public String getDataBasePassword() { + return passwordDB; + } + + /** + * Gets the sys admin token. + * + * @return the sysAdminToken + */ + public String getSysAdminToken() { + return sysAdminToken; + } + + /** + * Is manager product enabled (e.g., for GRSF records) + * + * @return true, if is manage product enabled + */ + public boolean isManageProductEnabled() { + return manageProductEnabled; + } + + /** + * Get the url of the uri resolver for this instance/scope. + * + * @return the url resolver + */ + public String getUrlResolver() { + return urlResolver; + } + + /** + * Check if alert user members is enabled. + * + * @return true, if is alert enabled + */ + public boolean isAlertEnabled() { + return alertUsers; + } + + + /** + * Get roles to extend. + * + * @return Map + */ + public Map getExtendRoleInOrganization() { + return extendRoleInOrganization; + } + + /** + * Get the solr index base url. + * + * @return the url solr + */ + public String getUrlSolr() { + return urlSolr; + } + + + /** + * Gets the map access URL to catalogue. + * + * @return the map access URL to catalogue + */ + public Map getMapAccessURLToCatalogue() { + return mapAccessURLToCatalogue; + } + + + /** + * Get the catalogue email. Default is "catalogue@d4science.org" + * + * @return the email catalogue + */ + public String getEmailCatalogue() { + logger.debug("Read email from resource is " + catalogueEmail); + return catalogueEmail == null? DEFAULT_CATALOGUE_EMAIL : catalogueEmail; + } + + /** + * Checks if is social post enabled. + * + * @return true, if is social post enabled + */ + public boolean isSocialPostEnabled() { + return socialPost; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.class new file mode 100644 index 0000000000000000000000000000000000000000..46382431fa3a89121d3d48fad4f776143d9fa959 GIT binary patch literal 3812 zcmb_f`+L*o6@C>vvEnEM45S&O%wucF-R(-dvaqrcLJ3KLB_@ziV2b_45y+A&$%N3Y zyO(Zb_Z#fm-EVB8bTv@6w%eX(-LwCx-QFWBu|r*c8V{EAeLCMc?|ZJwf8KueH2{y| zp9wT+7^PTG zDp+#!egbg~8_$^+%#3Y1h0M`~b1D~TXraD>@-(C-#g=a`?mm~94EKgLG#|=lkIl%- z+R2%~vz!87wvW1wADB)sYuaU{qmA-QK~VBF#O0ih4SbRv4f@`kZ8=u(q=r~e?=1I6 z-MmU-GqxtMMZ*L48b4^}0@qtH(1`~$v=&rQ1*PGko;on2w(0xBz3;@{3Jvcu(2N!h z9g~)$j+BcF%FCJywhGDSOncV!ELlgJEqgJ?1Kx?~2H>l`tQ>Y(QqXL4?d*t+ZaMb7T6qrB$-OaYQ!P-&-Z+er-I5pnH@G;D1|b2fq9jBqXMb8fNd zI+;*e#wwQVOz5Tk%5;*fl1Jq7VFOQK4};~gHiul8 z(&1f*XxLSkU-w}wH8;a9aDK`xMLD~fximU4a-=?=S}}#A2^`VT^Dd4wOIFp7$2|9f zl~!16lEHjCeF`TVy&PXHSxdWZlsT(^*}Ki%%Fh z83v4T6`7x+_9@RTm)0reoAx@TqSK|$!G3YfGX^}cl9TMWUf`dw z0@`a>LGvPBHgEyUl4IosKWx_`J>DQKMVd|ak|@`elMhwP<|hq&3eU-WP)0xvLT zVXtvikU7L5a(sG{1IOXiVvjNKWqgHw+*iRt*S6i|X_dFw3T&a_%o%Hj7Nh4>^mbRZ#YvbdKXMZTaaWt_rHl_=$m^io-itLDR}Faki@J zjJ%4U8TdJV!C;srLZ-{MHwtEChJF1ier4d-Qet}GRxz~UxA=VmzawaA3iWf|z#oK6 zb6zc!3p)Nt^=rL6y}V@EY~xERcb-!}UG{9z^k)M%@Dk4`&vQL?i~HATcFA*>Wzr5y zU|!a+x#prZQ*62Pc{OiZX(#Ju=~pIR&Si_-UM=~C$-us-G1<1(b%iype7B7XWJ)^x z%_!ez`b?;maE|EstAQlaCNSZ9@V&cU$?~ge2ES-MXDSIy$hC5}PP7$h-V&O=-80dKq0W zanZy>pkNcPn<%~+?+tfBVScYfM>D+3;pV<(0vWU@F2F*?haZO@SRoNc#3qu-A)|BIISP%DvqYMR-&809_|R1 zEVT)>ZZUfklXoz!fz~I8tFiTZm-W&`eQW$TMz)0iaq_QPn2Ic<`rbsdc7u9nQ**-Q zRE^69%E&i*9J}eM$JR6o%d;U5K~JPDRQ-wjs@|6}8>oJgs`pX#$U4=zdsXMxR2OJX zVzi@*I;AEBcz=jHRS0j4O^rb{8i#3Sf@Y=&^GIDZcEAcvwK7uY_*9KX#OM5)(N}m} z9C08rYDY%L$SCEc8XJlv~Gd{PEhwr zLYwF66w~4~C(juc#aTQ~kM74p2sd4|kIzMLhw=Fk?hbV03w&w{)2JP>mbcKIz%KsZ zLWN(1A4U7^h{9qmx0_?v`%=kNJCk@aejCr<#g)1KTliW9Uw;Fa3IE#_eD@~0?&9iP z>Ib**BeM8$1us_c%RBf@6J)sw|9%n8@$0eclax$d@4tgT#SptrtL>zA5;qB4s$z)s z02Fz3_{L*K`rHrDi!w5tvxl)v=@razLg(>pNV<=hfkpf!B;848yb_Y`<%tT5p^4J% zxQ#ne+_oX!roDwjA^*$&<*vp@x!j~LUZq>BnSUnAp)UF&(f?*t^Cj8@n$GDP= literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java new file mode 100644 index 0000000..9136507 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/CatalogueUtilMethods.java @@ -0,0 +1,139 @@ +package org.gcube.datacatalogue.ckanutillibrary.server.utils; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Some utility methods used within the library. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CatalogueUtilMethods { + + private static final Logger logger = LoggerFactory.getLogger(CatalogueUtilMethods.class); + private final static String HTTPS = "https"; + private final static String HTTP = "http"; + + /** + * Maps the scope name to the ckan organization name + * Use getCKANOrganization() which uses current scope + * @return + */ + @Deprecated + public static String getOrganizationNameFromScope(String scope){ + if(scope == null || scope.isEmpty()) { + throw new IllegalArgumentException("scope cannot be null"); + } + ScopeBean scopeBean = new ScopeBean(scope); + return scopeBean.name().toLowerCase().replace(" ", "_").replace("-", "_"); + + } + + /** + * Get CKAN Organization name by using scope name + * + */ + public static String getCKANOrganization() { + ScopeBean scopeBean = new ScopeBean(ScopeProvider.instance.get()); + return scopeBean.name().toLowerCase().replace(" ", "_").replace("-", "_"); + } + + /** + * Ckan username has _ instead of . (that is, costantino.perciante -> costantino_perciante) + * @param owner + * @return + */ + public static String fromUsernameToCKanUsername(String username){ + if(username == null) + return null; + return username.trim().replaceAll("\\.", "_"); + } + + /** + * Liferay username has . instead of _ (that is, costantino_perciante -> costantino.perciante) + * @param owner + * @return + */ + public static String fromCKanUsernameToUsername(String ckanUsername){ + if(ckanUsername == null) + return null; + + return ckanUsername.trim().replaceAll("_", "."); + } + + /** + * Generate the catalogue's dataset name from its title + * @param title + * @return + */ + public static String fromProductTitleToName(String title) { + if(title == null) + return null; + + String regexTitleNameTransform = "[^A-Za-z0-9_-]"; + return title.trim().replaceAll(regexTitleNameTransform, "_").replaceAll("_+", "_").toLowerCase(); + } + + /** + * Convert a display group name to group id + * @param groupName + * @return + */ + public static String fromGroupTitleToName(String groupName){ + if(groupName == null) + return null; + + String regexGroupNameTransform = "[^A-Za-z0-9-]"; + String modified = groupName.trim().replaceAll(regexGroupNameTransform, "-").replaceAll("-+", "-").toLowerCase(); + + if(modified.startsWith("-")) + modified = modified.substring(1); + if(modified.endsWith("-")) + modified = modified.substring(0, modified.length() -1); + + return modified; + + } + + /** + * Utility method to check if a something at this url actually exists + * @param URLName + * @return + */ + public static boolean resourceExists(String URLName){ + + if(URLName == null || URLName.isEmpty()) + return false; + + try { + // replace https + String urlToTest = URLName.replace(HTTPS, HTTP); + HttpURLConnection.setFollowRedirects(true); + HttpURLConnection con = (HttpURLConnection) new URL(urlToTest).openConnection(); + con.setRequestMethod("HEAD"); + logger.debug("Return code is " + con.getResponseCode()); + return (con.getResponseCode() == HttpURLConnection.HTTP_OK); + } + catch (Exception e) { + logger.error("Exception while checking url", e); + return false; + } + } + + /** + * Builds a string made of key + scope + * @param key + * @param scope + * @return + */ + public static String concatenateSessionKeyScope(String key, String scope){ + if(key == null || scope == null) + throw new IllegalArgumentException("Key or scope null"); + return key.concat(scope); + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.class new file mode 100644 index 0000000000000000000000000000000000000000..ef5abeee8576b48827e0bff430941ce179babf8d GIT binary patch literal 855 zcmb`FO>fgc5Qb;dq%k3-Z79(4(NbDI5BR_lgp@{ZV%3RLZxRVE*4ka1EyhN>>q_vi zI3aQ12k@g1vuR9y;l{xuKdX0V-kF_WzkmD$fLHLe2{i(KE)zS6i-_B2OtTojG*1d{ z#~)c%XpyEOl1zTF6_*!W+U7{vlq)6jtXHbLT1ycXnyV(%32dCR3udP*OKd+n=dmWx z>78^(p&#^VIHgVyo;dID(7O^+%#bCo39R+RF;uwWad-)k} z!3sQV!+m&w0bB{2#7yk`7fI}n#k1^KZ$sc-c(iH#z literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java new file mode 100644 index 0000000..a141eb9 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/SessionCatalogueAttributes.java @@ -0,0 +1,17 @@ +package org.gcube.datacatalogue.ckanutillibrary.server.utils; + +/** + * A list of attributes that are saved into http session. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class SessionCatalogueAttributes { + + // CKAN KEYS (PLEASE NOTE THAT MOST OF THESE INFO ARE SAVED INTO SESSION PER SCOPE) + public static final String CKAN_ORGS_USER_KEY = "ckanOrgs"; // organizations to whom he belongs (shown into the portlet) + public static final String CKAN_HIGHEST_ROLE = "ckanHighestRole"; // editor, member, admin + public static final String CKAN_ORGANIZATIONS_PUBLISH_KEY = "ckanOrganizationsPublish"; // here he can publish (admin/editor role) + public static final String CKAN_LICENSES_KEY = "ckanLicenses"; // licenses + public static final String CKAN_PROFILES_KEY = "ckanProfiles"; // product profiles + public static final String CKAN_GROUPS_MEMBER = "ckanGroupsMember"; + public static final String CKAN_GROUPS_USER_KEY = "ckanGroups"; // to show the list of groups in the portlet +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.class new file mode 100644 index 0000000000000000000000000000000000000000..83efa901ee52408e171455ccc57899476cecd51f GIT binary patch literal 1600 zcmb_cX;TwH5Pg$#6IYHXpnxcXnykQj;z2}G$dTfRMMA2Aewl8}Ix$A`Bf{e2426x9hYSY%|24 z;E3hU1q)WX_AZZ*G=E9DETbhsh;NL{zdy}DcPE3+NM9v5Kd>x43Sx9(@+pqkRm07xSruB!Ejzh4|*A5 z*=Bq?eVS_iv@26iQ1%5CQN$F)6%3FVb=L{r3jZY)ap6}KTp@8tZf=|Jxox@^jn!bgYPcm{wG5${Q{z^dyQZ+EGl?+Lf^UYQ_g^%RNZnMCK$2?q zUz;9-;ycG(IG@g(u7qme;Z|T!=u$ef@Uk_nIair>jggT1v5E(vQN7=K(5%HhZ|by? zt>TJ1M|sJj6Sy^F-jpr<rdJ#Yl=s8q%}qpuA49JhH`a;VW1r)fG;4@8jGa`lNX=lIoY{ zpfrb~smszFj(wx(@Gkm_mB=mzi5#>BQXyT0(Jc{rDWBpoCd(6VqQEfWjboyTs?*9S zDyn^g_CX#iNX4YHN5ZH_0Zo_$blf73&}5P{5t{byVx+PZ)($IKQSVB4-~hMB{zhZJ k%SzBtJ#1oVL{bn)rkHksN8iEzpBF-wB13qBX}LcA1;>4cWdHyG literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java new file mode 100644 index 0000000..947d1d0 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/server/utils/url/EntityContext.java @@ -0,0 +1,24 @@ +package org.gcube.datacatalogue.ckanutillibrary.server.utils.url; + +/** + * Entity context for uri resolver + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public enum EntityContext { + + DATASET("dataset"), + GROUP("group"), + ORGANIZATION("organization"); + + private String entityAsString; + + private EntityContext(String entityAsString) { + this.entityAsString = entityAsString; + } + + @Override + public String toString() { + return this.entityAsString; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..9109cbda47a5ee8d9457cbfb4a139cae559d31df GIT binary patch literal 3296 zcmbuA3sVzU6vxknkOWw(rhr9l4W*Q1Nmx;?zOt*U-!+;P0LSF zLePPG<^$7kOt)$*m+o2RAVo<*ee%@yj1|kbO~?MqEIAe~<6~^sEWd7h?zOo~g2cR_ zeY2ih4@@^$Go6Ojwf0YQ^oNb#4+-k9D}pkMEfXt&Z@bkgK?&EaL1EI|v=^+$f)18_ z%M74&)vj64RofKQWtO}~fJ@${<<3D<`fkHK`FaFQ>oc5K-O{dtnJ#t zw4lyheho%uy^7UCopeN_L-dBA{foA1Ej4N-%U@LKIbYb!T z#TRaF<@P%NDkt-=a_Lp>tmoIdNzmIGX|#`}cQkrUN$+a3Ur9NQ4p5rk>KYwXX9bNi zN*dSbbtN6ws82~JH0q}Tq^N2IoSD8{elHDP*VXI(m@sgHQutiuGliQ<>c-hjSQXtk z-I4onKD)O_kZDw4A1=ncOyuU-Oqx}yT1vA1G&7YZj(8!FxsqhGR7pN+1+%qT{WxXpoopwT>? zf|?bt;g_u|HqXMoos5Okbez*mLujH-{C80g9i|keA$MbBcVOSaJt$>#pj^>^az*#a z6}=}{be>$%cXCD7$rU|^wI4b$&hQ+>?j%-$wM&0ShkudRj^fGY2p1B-coUMQF40?b z3_Dhk#gi5M4d7m^ldM1=YtoQjXwtA=Y|@B6kZ97VKA3D$ULQ;~X-pqXH>s!(b~nk; z`+J%+(Xu%%_2{rU2B!-cG)0V#aab{6^*D{t1m2v$^CX?2QG0!e+~&|GWvE)ttAI}-^Jk@o0d;HFv1I6&kgluHKMyh-1vwuJG8qpt z90i#L$fY(Q99NFO`>_!jiGo~>1^FNzWF!i*0FcEtAe>ePnL^BVBGLhgtNAI7{uD{g zaxBO>nhrmnMvZWlB=uvc+9=2hKvvs;a8)tL`Phi$qY=3t3vwYoBKauDO@Q2L1Hwhk zATzNbV^NShu^<=YLB^sWWq?%LfN)PS$ZRY~F$z+R1-TRtQjCJ!2Z+-KgjeRqh++u&^CRNxrPViVV18ed89MFO*i=94nItF zI=W5e%v~kt`FumkV=UiOa*<_6$p*`=k|(xlGgF7WO^sGQ2H*nGcbNB2P(|NUiMHrl R>|4J^Tf4tT4`uKk{Rg1xAZh>r literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java new file mode 100644 index 0000000..ccc7c49 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CKanUserWrapper.java @@ -0,0 +1,134 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * A CKan user. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CKanUserWrapper implements Serializable{ + + private static final long serialVersionUID = 6264706263035722775L; + + private String id; + private String name; + private String apiKey; + private long creationTimestamp; + private String about; + private String openId; + private String fullName; + private String email; + private boolean isAdmin; + + + public CKanUserWrapper() { + super(); + } + + /** Create a ckan user object. + * @param id + * @param name + * @param apiKey + * @param creationTimestamp + * @param about + * @param openId + * @param fullName + * @param email + * @param isAdmin + */ + public CKanUserWrapper(String id, String name, String apiKey, + long creationTimestamp, String about, String openId, + String fullName, String email, boolean isAdmin) { + super(); + this.id = id; + this.name = name; + this.apiKey = apiKey; + this.creationTimestamp = creationTimestamp; + this.about = about; + this.openId = openId; + this.fullName = fullName; + this.email = email; + this.isAdmin = isAdmin; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public long getCreationTimestamp() { + return creationTimestamp; + } + + public void setCreationTimestamp(long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + } + + public String getAbout() { + return about; + } + + public void setAbout(String about) { + this.about = about; + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isAdmin() { + return isAdmin; + } + + public void setAdmin(boolean isAdmin) { + this.isAdmin = isAdmin; + } + + @Override + public String toString() { + return "CKanUserExtended [id=" + id + ", name=" + name + ", apiKey=" + apiKey.substring(0, 5) + "****************" + + ", creationTimestamp=" + creationTimestamp + ", about=" + + about + ", openId=" + openId + ", fullName=" + fullName + + ", email=" + email + ", isAdmin=" + isAdmin + "]"; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.class new file mode 100644 index 0000000000000000000000000000000000000000..4be9dfe3e5a2ea6ff7dba850788f88a1cc098dcd GIT binary patch literal 2209 zcmb_cU2hXt5Ir{^-i^Bj>Lw;JDL5?z+i_UFp#%qtA*3WYQG-IOLZ!96ayD#sEqh&w zxBiy?f>vrm)k;;L`=e0L?5-2nZ2EwB@Vzs4=gyon_l*B}`^R4Zu3=Ndh{B5BX_>7? zuWp-7E3g{;xqho>n~hhN*9#oib?P0f^V;n0SRK1*R(br8L0voe#&)g1@xAVj)7CJi zaBA23(K21jYndDMUAqw|Xx(0HW!8_rZUr63Yb`0H{C-@+-`lf2-WUsBw{3p8>v&GE ztT0+AZu7M2H|;b=al$|vA1Rz%cRah++pF81XI9v)6WQ^U2mm zEo$>paa)I;#yQMs$SdT8Y;vf9&+!GD+OpZ|`9UiER0CY%BMle+^S06J>CkkH>zGKR zgtCSOh4Xwwv*r6OqLcR|);fh^Zg%X3?=_uJECv<@fzjBp8?S19Q0uv_!tDRiQ%Do< zR$obzh2j9nLoKB#$-|hbL27Y`=xBn8B3iV0p>IopYF~nq>Cn;mH0%{e25R;g z=$C{q=BU_F{*jDfL%Eve5$UDG)?Z=S=<+h7g={Kp`w__K z@$RvC_XmKa4uPcNwkm>80+JmDQcVPMJsC)L7|3ImTRjGdNK`s0$@RGv)frVZSkg3Ef LQK&I$1RMVX9oUx= literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java new file mode 100644 index 0000000..c5d12d8 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/CkanDatasetRelationship.java @@ -0,0 +1,96 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.json.simple.JSONObject; + +/** + * A ckan dataset relationship. It is represented by the following fields + *

+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class CkanDatasetRelationship { + + private String subject; + private String object; + private String comment; + private String type; + + + public CkanDatasetRelationship(){ + super(); + } + + /** + * @param subject + * @param object + * @param comment + * @param type + */ + public CkanDatasetRelationship(String subject, String object, + String comment, String type) { + super(); + this.subject = subject; + this.object = object; + this.comment = comment; + this.type = type; + } + + /** + * From a json object that must have the properties listed in the class header (comment is optional) + * @param object + */ + public CkanDatasetRelationship(JSONObject object) { + this.comment = (String) object.get("comment"); + this.object = (String) object.get("object"); + this.subject = (String) object.get("subject"); + this.type = (String) object.get("type"); // TODO convert to one of enums DatasetRelationships + checkNotNull(object); + checkNotNull(subject); + checkNotNull(type); + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return "CkanDatasetRelationship [subject=" + subject + ", object=" + + object + ", comment=" + comment + ", type=" + type + + "]"; + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/DatasetRelationships.class new file mode 100644 index 0000000000000000000000000000000000000000..9b4c98113553785dbec3503b4c4ebfbce65d14ca GIT binary patch literal 1620 zcmb`HTTc@~6vzKVOLtoqs36Ei@rFR_WyQO;B8Vj#Dga4exxDEFtW=Jxao1fZkGJ! z9z&)k_Jv=IDuK^XD)*sIfnm6lRQOJ-61-tBY9e$GL{xbb22^vT!J~@WQm13kordex zlxupQ8t`Ma);-sM8&%?fVMs1Tt(#z|w7LCkerK(`U9uQ9UiInNdeNaWZoI;fSjz1% zB-ewQ&@q?+!-RoJoM1>5yDpPU<)dL*ap?N>!js%intZ1X3?ijNlW@|2CP9~Q+JG)0 zE#aJjw1kX=3kEV0h9oQ*7?NN}xM;wTFf8GUfnlWN>Z*Yej53UtU0-ZA_o^a%!K-a0Brrh@#SJ&29uBzI6tsA}laK9&!jqn9{@J2&GHB|sTO=d9H>^AHTwmV39M7tO`&eVR*;{4Z z<55)TIojW{M{UZBM551FK{Is3hAUse^uKQ46&XX5u-v-O<7P;HFMCqUJjK4Wvr<@H zCWR#EA0)jxEwu=cB^fG93RITFr!47CS(2Qxq&8(qXh3#G%8W84Nx4}Zqr788KZ)h% z-B&PsY&`J^$3J39!Aw%Ytb$X63g#4?Nhvt1;Jl__UcrK{U{OIX+wsdQx|HoWUe4;@ zs8*tlDa%f_F>Bd_ZOmDAs*SUjt+g?4*?Jp`mYt=oJQ>=%Y<-0Jfet!=W%^y98wZTj z9XgH~Okj~N^$ncB8m6#`X}qT0U25=}ijYxs>ANj2(?I1&wfx1CpK$#sX^I@s4KmbP zqog!DDs~gMy5YCzJ;?CMHcb0zB7bNXWk1gnv!8MM(tCQ+IbtUp`+I~m$#SKeBTqiE ZR%VRlKjXo7u>Z#m;GxR7jz`Ltegi + *
  • depends_on + *
  • dependency_of + *
  • derives_from + *
  • has_derivation + *
  • child_of + *
  • parent_of + *
  • links_to + *
  • linked_from + * + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public enum DatasetRelationships { + depends_on, + dependency_of, + derives_from, + has_derivation, + child_of, + parent_of, + links_to, + linked_from +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.class new file mode 100644 index 0000000000000000000000000000000000000000..fde731f9554a124868c8fea5be257017f5f897f9 GIT binary patch literal 1674 zcmbu8T~8B16o%g^&@WfP@};6cRfHDGsvwHBs9-djMokbBW4xHQld`z%lI^aE-uj2s zC?=YC>4iVa_|9&HQkE;z?9ACS@1A+iM}PnM{u96g)>23alwGfBHtRu6nGNa7Iv?9@ z2Fk3zkxt-Swr$ls>Af>sThdbvvnrj2!$Krmg{Uhejp&82%KDVot7^he^c6l>ie8oe)?-P|3M%f zc=n5TyQ(FSs~%jm?t5e?Gak>Mc}?l?0-q77%h2`6bAw&l`t!%W+M$`eV>y<;BG5Ba z*c9kpa~mp)9t;~ejhsM#)pFF+V5g?M7ZGc&>ei*bDalXvwzJpYvKXyW{g1Md`$SXu z8~dpZ%@mF%mw~_q0|rh~-s+SO&m2|joCc$yhw7oDTr_Y>M;VNw96A>;qOYQoY55fc z{aS8B@_)5#BZuYGvZ8^34z_lg)4m%uCxv-|(e9S52A17WUK&?<*f~m*uh^=v)0Her zxURc0p{+#&H?YM1$=zM$Gz3a<*&iuL`=W9hx0v|cB%>e7yOPFjrWhVX8Paoyl@2{& zGIVfU#A{7)&%hkU1hVUH;MLVbOAqtu&IIOls>ri2J$(B3JBJj~v@`s-C6MLAUWPWi z5$-H=xU-Jjv($1FxeoGefxF<|SNw*dPoZoi6eYNxK`+i?l$H^R=sC+b!Ar-u>HsG9 zD8Lt-|42syIzTdXj>UdFj*0fiD^%-?lEvAtINyE!IJ27wBaB3<_Vqft&QV`H84Hr{ z2Fb^QT#5(DcY|Ce$kZ_)y2u*jaxBPHH^_7>$aFl&R5wVGAhXAS=q_uJnOKlQH%KWK zWHuh8&<%2xAlHro(PO4TILTb~jI_dG1u8#KdYLo7;aZWyvWJD-O)j+a+Fp+ADQ%Y{ myP)j~mp$A)NFc|t1Qs#OzibIhSf+h2q?P?4y-!sFtA7D5FD}Rc literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java new file mode 100644 index 0000000..2e7695e --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/LandingPages.java @@ -0,0 +1,57 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * This bean offers the following information: + *
      + *
    • landing page url to the items page (within the portlet) + *
    • landing page url to the orgs page (within the portlet) + *
    • landing page url to the groups page (within the portlet) + *
    • landing page url to the types page (within the portlet) + *
    + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class LandingPages implements Serializable { + + private static final long serialVersionUID = -5617896049674346109L; + private String urlTypes; + private String urlOrganizations; + private String urlGroups; + private String urlItems; + + public LandingPages() { + super(); + } + public String getUrlTypes() { + return urlTypes; + } + public void setUrlTypes(String urlTypes) { + this.urlTypes = urlTypes; + } + public String getUrlOrganizations() { + return urlOrganizations; + } + public void setUrlOrganizations(String urlOrganizations) { + this.urlOrganizations = urlOrganizations; + } + public String getUrlGroups() { + return urlGroups; + } + public void setUrlGroups(String urlGroups) { + this.urlGroups = urlGroups; + } + public String getUrlItems() { + return urlItems; + } + public void setUrlItems(String urlItems) { + this.urlItems = urlItems; + } + @Override + public String toString() { + return "LandingPages [urlTypes=" + urlTypes + ", urlOrganizations=" + + urlOrganizations + ", urlGroups=" + urlGroups + ", urlItems=" + + urlItems + "]"; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.class new file mode 100644 index 0000000000000000000000000000000000000000..e1b4cccfc4eda399c015b49a56f7149858e54139 GIT binary patch literal 2585 zcmchX%W@k<6o&t?b&EZAV&NnxK%zK~B9G;WU@i%clVBSggD>EVAeG8uBuyz3oTfB*ZZUjfYG zZW03q<{EyjSgW+kPO)kSc7?xsqtNG39 zyC2Y>fdRK_Al`W7Ilh4t5>V3#R=JnjbN8H`$NT(`#7)<8gIjc-pDNMMVx#H|VGz%n z7{_S?C)Zrh*=X&R9e*dJPOmj8cD-aX5=PP4j0F$erh)mj|Byh2@p=AuaR2AdROti^ zTrgo`MAStSqoKNF;$)~Un>ZD!D<;N5HDw|ls%aC?V1#+CIl-=6*LZ&Fcm({;t5Dxh zYeJTrNYcTEy3{01Lp931rQRDJ<)?pb#AzWn96!8it~bL1NO7wpP4Uw$2UEOsm&5$J zepDdC{McQkf<{<#Nw8+lMk{fl<<_f?pTZs1X>W66@3D60hcJ%?DXgNXB@=IAnW?b% z_Z^SWGrCk9OJ3)UxfI@FmI_&^{P`5vIHQGZPyKUmjfp5^-74h|~9HcugY*caT`VKd$r%#w+lm@zQ4ty+EAmDU~W4eqL>0T)>>gZ#yj!Z{>4vg!D? z3}A>q7L?K~CpEK})XY*+GYd)0EF(3uh&YeY2iuV28LnnI8=T|TQ=I)lnPoVNd(bFG zqjOYdXoTnRJXhl21&-q27h0w`7sP=z-Nt#V&_>ppX=B35#M+p&GVwNYRwmI#-pVA~ zu)62uR5+J-&Lq`kc1Di1egzriaRF1@u`ta)Vb}`K=`ip_l>mV+NJlB+f^-y9CVP^G zm{O96xKfgegi?}>Bx5LGrV~k#bC`-BasGQ64G;q~m(6S1G+c%JlceDmttDj%m4a@7 zVIr^d_#4W@nb7Jeh(sp{121YpvQd!RT99jckZcrWnIJ2DKqQBfftR!(6H$spX}6y%W>#46yysn$ebRe=UE85=1YQn z)dxh{S3vlTa+D7IPQ8?X{WIq8rf)yR8y5Tc0E_7r4%AuEtD&9{{Z6PSMX!fCCweo~ rdC~8M+7i9Z;Q+hcAk*r7dBSJ<8{EOSxQ{120ozBf<@>}Nzz6>T)aItN literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java new file mode 100644 index 0000000..2b124c3 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ResourceBean.java @@ -0,0 +1,152 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * A bean that resembles the CKanResource bean object + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ResourceBean implements Serializable { + + private static final long serialVersionUID = -5275448097250176185L; + private String url; + private String name; + private String description; + private String id; + private String owner; + private String datasetId; + private String mimeType; + + public ResourceBean(){ + super(); + } + + /** + * @param url + * @param name + * @param description + * @param id + * @param owner + * @param datasetId + * @param mimeType + */ + public ResourceBean(String url, String name, String description, String id, + String owner, String datasetId, String mimeType) { + super(); + this.url = url; + this.name = name; + this.description = description; + this.id = id; + this.owner = owner; + this.datasetId = datasetId; + this.mimeType = mimeType; + } + + /** + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * @param url the url to set + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the owner + */ + public String getOwner() { + return owner; + } + + /** + * @param owner the owner to set + */ + public void setOwner(String owner) { + this.owner = owner; + } + + /** + * @return the datasetId + */ + public String getDatasetId() { + return datasetId; + } + + /** + * @param datasetId the datasetId to set + */ + public void setDatasetId(String datasetId) { + this.datasetId = datasetId; + } + + /** + * @return the mimeType + */ + public String getMimeType() { + return mimeType; + } + + /** + * @param mimeType the mimeType to set + */ + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ResourceBean [url=" + url + ", name=" + name + ", description=" + + description + ", id=" + id + ", owner=" + owner + + ", datasetId=" + datasetId + ", mimeType=" + mimeType + "]"; + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c2b1cdc1c65318bd90bb6597deb38404a48712 GIT binary patch literal 2154 zcmb_dTXWh*6#mv+1X#f~Zip}GJ!t@^QJpmD1?t+y*r5S4V{E2OpB7n_l?aJhBzOFO zI@8zGnMpkDG}E`v^r1hg)3b|OV<&kk4`_9?=X~dU=fLz6Hf%HO zS;ip`xJf_Pw?oS?pKvb>9M^Svf{PPlc*KQuXzcl}HLTLzj_|`lOSFWoA&OOBf~J$a6D@_?Ds6O&wH-LkZbrRcRO4-QdS=`h+&rE367j0 z!&TGwjx7=F`?45SKH#PkoG^S_m_#0muhNqIZ|Jy*j~G&cKO##s3$N8JproNl8M~Yw z9V-%HI`A9*50MDjSZECMEcD4F4FdSeQk{>f+7H4@TT$3}$zfT}K&nLovH_ff3$vRjdrYQ~n& uuz6cL85L*bgefO7p0wO_5k`r0WJWVNRyxDO-@)E&H-$$Evw@~McmDyS^AkA$ literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java new file mode 100644 index 0000000..196b655 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/RolesCkanGroupOrOrg.java @@ -0,0 +1,39 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +/** + * Roles that user can have into organizations/groups. + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public enum RolesCkanGroupOrOrg{ + MEMBER, + EDITOR, + ADMIN; + + public static String convertToCkanCapacity(RolesCkanGroupOrOrg role){ + + if(role == null) + return null; + else + return role.toString().toLowerCase(); + + } + + public static RolesCkanGroupOrOrg convertFromCapacity(String capacity){ + + if(capacity == null) + return null; + else + return RolesCkanGroupOrOrg.valueOf(capacity.toUpperCase()); + + } + + /** + * Get the higher role between role1 and role2 + * @param role1 + * @param role2 + * @return the higher role + */ + public static RolesCkanGroupOrOrg getHigher(RolesCkanGroupOrOrg role1, RolesCkanGroupOrOrg role2){ + return role1.ordinal() > role2.ordinal() ? role1 : role2; + } +} \ No newline at end of file diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.class new file mode 100644 index 0000000000000000000000000000000000000000..859c1c2674d0a498be89cbcbbff319a6c5e49ae5 GIT binary patch literal 1152 zcmbVL-*3`T6#gy+3SHe09dkeYJr&rbS=1Q=S+=k)qHIenBOyLrN@bm;n9?rczf$(F zMdRYLf0Xgu4o6>np-Fr0x#xV}{mwn7zyEx{1n>eS88L>JeXpx^&7f^*9qx0JUZ>v; zEY1AP-N3gU$8LMv8)}1N?pYnp@VRfvh%?Nd@Kdfi-0f<*8}u0DUA?Y1^j(I{`ZTO% zhU8AQQETc9Gy1{N{%Uilexw@=uRl&pn5vkL?b`kpgOo2c8RFG`$4VigfMHHW1~=){ z$~YyLuTP3He9v~fX3n!;SMpCTqs7N7ARCU|64uW3W@*2GDSPa>E z-{ek{d$#byO$8F>NP>TC59riW?gSPs-sB5Y)~DbB9?5vfkcsFX4t%Sp;xSek(%kd- z(CmL1G8CiL9kx#_(=XQ|1^?Tkim92Qy2DQl@1n5rr4**?hq!>eiYF*Ayo%CR9X=S8 zBU-M{nbakQj7CH;`hjO!d$zb_B^<|+NTON|yX$g4@F?&$!X%_;w>PNE68$jJ z_M(^ofGjm1$SjH0QzTAS!3^c8y1@Q{@rEph7Ximrc8>B|)k&A09=UAQqlazolNDbFAR)kO@yNi2c z_$C!0;JFbNTJNReWve38>`TiRxWE3DB3Cl5*x0p%GXh18rDPm{4c%U6omi) literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.java new file mode 100644 index 0000000..ddc8fc2 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/State.java @@ -0,0 +1,10 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +/** + * The current state of this group/user + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +public enum State{ + DELETED, ACTIVE +} \ No newline at end of file diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.class new file mode 100644 index 0000000000000000000000000000000000000000..143b4006fdec1b43a5c1a542b98e931126e4596c GIT binary patch literal 1695 zcmbW0>rN9v6vzKV3oUiASgr~}!78N!E8q=Fy#PWWjeICJQR9bcJ1L9HF4>C-K7{Y# z2NO*c5>0#nU%{8~35;iE3x%@y!8E&b_RKkRe)B)4KmUCD0bm|$F|;u(*iK!qSN)36 zYuw{idQ7|S3%&Y=TfS$QrcrUYv#-0`+z~asgO+nVU|XTXdF3$>i!J*P3Jddt}SVbx-V)*|BI?hWC&mlASCwM3?QF zNFah<4c)lJkSrROc;@d`gtHZ3rHXcyn`KU@gxPRLy={X|%NPG!pFG2by6~t};|>J0 z(FulO4I1LK>z>?=W;Y~nPmprzt}jqdqZBA4 zFpW9chIxv}o;`Q6EF%A5&qRLjS)K%z{gsmLi!RI$7~YLQ_& ztk^$}r0LPrk%4Z7I382Glt)QKjwPDi*AjO{!%a*vBucjLRK=KtLf&dI)kiHl$Q^}*`wqP&!1w$WOk_SVRuVSQ;{E%)Ck)?8@Uoq4yEpGq}(ana{ z3H|E3qfuU>$@@v_(NK_dE67MF$apwNx)o%MK*rAjkpfGQYoQ>SR*+06$c=E2Oe@F) zfn?7CksX#G6QLm4R*+mMNG=>C+X^yGAT#HH$PtquG{f|k1Lmqh1q$CW{UW6wVpa~z z0dA-6AK(GmX=xV%J0tB!ft{816S5Dm{ONeMQizg0i$2WJzhxc^WH*Pja6F_>RmSRH D{p~W! literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java new file mode 100644 index 0000000..fee060d --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/Statistics.java @@ -0,0 +1,54 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared; + +import java.io.Serializable; + +/** + * This bean offers the following statistics: + *
      + *
    • number of items of the catalogue + *
    • number of organizations of the catalogue + *
    • number of groups of the catalogue + *
    • number of types of the catalogue + *
    + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class Statistics implements Serializable{ + + private static final long serialVersionUID = 2871906712366452266L; + private long numTypes; + private long numOrganizations; + private long numGroups; + private long numItems; + + public long getNumTypes() { + return numTypes; + } + public void setNumTypes(long numTypes) { + this.numTypes = numTypes; + } + public long getNumOrganizations() { + return numOrganizations; + } + public void setNumOrganizations(long numOrganizations) { + this.numOrganizations = numOrganizations; + } + public long getNumGroups() { + return numGroups; + } + public void setNumGroups(long numGroups) { + this.numGroups = numGroups; + } + public long getNumItems() { + return numItems; + } + public void setNumItems(long numItems) { + this.numItems = numItems; + } + @Override + public String toString() { + return "Statistics [numTypes=" + numTypes + ", numOrganizations=" + + numOrganizations + ", numGroups=" + numGroups + ", numItems=" + + numItems + "]"; + } + +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.class new file mode 100644 index 0000000000000000000000000000000000000000..27160464aeba3ea8ec1ae11970dbc1cb75cc6421 GIT binary patch literal 497 zcmcIgu};G<6ucKo1EEkTf}O2^ga^h}l@Ov+R3R10>?9^NxOU|vsC*U^5(6K=MZWPxyaKhQ6iJ2OnDoZS4yP!(pIH5MkikSM^Q|r zSD8=?aWe&&3lIvLgUUc}(QTtj991Pq{gbo`99Cq4y; exJFAgV&?_}*#C5)g-vGc#}?YlUfaw9?0f+1jfvI( literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java new file mode 100644 index 0000000..384b652 --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ApplicationProfileNotFoundException.java @@ -0,0 +1,12 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +@SuppressWarnings("serial") +/** + * Thrown when no application profile with such information is found + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ApplicationProfileNotFoundException extends Exception { + public ApplicationProfileNotFoundException(String message) { + super(message); + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.class new file mode 100644 index 0000000000000000000000000000000000000000..fb41953a3f35a2a79e69a6104f58565e5e0774cf GIT binary patch literal 767 zcmcJN&u-H|5XQf4)3^#LNn=|6UEEt}QGGz1iYi5Iia==v${$V$ZJepI;OttvYgC?q z=iz{mIPd^G0FS_9AjWRg9^k-*gLgf%zxn*_jKBZ-`VGJ%+z+rKFg7-g)1;VEJd<7~ z{A4CAC{ErhpXJ~O>M&lID|=oi+UtBg*i^JM!M3FT!rKusWg zE8ojFlRAyB4g}hctdiM;tYdKe>{viN7uYy5+Igw{L}mr8z5Mv_$Ir0+S)g^?Kk1DJ zqc^Ah;js6#FVGoW3lF_jIz3p&hQRC5oGeAkMGM2bpGzGXO_98I8|9aFBc;7zf?1cC zoT6#rBVEGgoYS-@RUG+9vRHMs9fA52rIkMvSnWQT2-J?uj2c))r-_>g1-80>8Y{up zKxsNF7E`h#InAiNfl0Upk{iMCGFdC_2)r8nmx&w*1PgLbru_ZJ&=fYI6CRvE_aElD zUv?Zj;Jfp`vx0kAL!G0biq<)9;Ko(lWI}LHTD-QIcwEImu-j>V!RDu`=oYUHJ^+Jt xMz{E_$pwsI8@G8cCBmh|A(JIr-`)F*LWk{ymBRKVwNzjpcPe87ce$F4{|22v#H|1T literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java new file mode 100644 index 0000000..feca2ae --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoApplicationProfileMasterException.java @@ -0,0 +1,20 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +/** + * Thrown when there are more than one application profile, but none of them was set as master + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class NoApplicationProfileMasterException extends Exception { + + private static final long serialVersionUID = 5874713540422734005L; + private static final String DEFAULT_MESSAGE = "There is more than one application profile into this scope" + + " but none of them is set as master!"; + + public NoApplicationProfileMasterException(){ + super(DEFAULT_MESSAGE); + } + + public NoApplicationProfileMasterException(String message) { + super(message); + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/NoDataCatalogueRuntimeResourceException.class new file mode 100644 index 0000000000000000000000000000000000000000..019fabc0fe1c2c6ba1cdc978b4fd61310b61df70 GIT binary patch literal 728 zcmcJN!A=uF7{~turAtb&*aC`PmK#>%9*n0N64DlfDLqhVVmz4X_G1~{&XAc|gAd^o z_!OQ@Jn#TK1vlOT{dTS800%A}c6R?WzwbZ)`DQP!f1Lw(g{J}L1l}8)L`j^DC>l#I zV}4STWE91prOv!cQ#G>EevRCTv^0+BEb5yMQ|*7`L8iT$&;dD<*_gU#F`as4bbyjT zEnL$Z#+qrHxRcqg#jHrjcq{ZOVEE&MjEi*MhrE(L0x?(WV} z@9^V(cQDv_+ZCwyZj1-sDxI_zu`JN+n=nro&fQJ2DPVY!beNbm>BnxB^iniWJ!wM06mei`}C2-OFX+yc_N9S>Xp! zQBg%okrZ^){0j>H0pjgpLIHFX`!T!oW@p}h{(f-@;0f-xupn?~Y#!!mHK8z*PNqBx zlUEd`Z>6rBDhf5R(!LAJ6KN?6=`2jh&QwZ~&R!X%U38YxsZ&O`&=Baqkuw<@*awq)Yy`A|R{3aku_E}hhFEQ^Yk(6&Ru^TH*FRSTbz-G;H8DuU?`*m)K*b=Qg(={Y7Do X?euDeji0Q!0`qaFHYRYFtJ(Mux}L3$ literal 0 HcmV?d00001 diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java new file mode 100644 index 0000000..bfcecaf --- /dev/null +++ b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/ServiceEndPointException.java @@ -0,0 +1,19 @@ +package org.gcube.datacatalogue.ckanutillibrary.shared.ex; + +/** + * Exception thrown when it is not possible retrieve information from the ServiceEndpoint + * related to the Data Catalogue + * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) + */ +public class ServiceEndPointException extends Exception { + + private static final long serialVersionUID = 7057074369001221035L; + private static final String DEFAULT_MESSAGE = "Unable to retrieve information from Data Catalogue endpoint!"; + + public ServiceEndPointException(){ + super(DEFAULT_MESSAGE); + } + public ServiceEndPointException(String string) { + super(string); + } +} diff --git a/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.class b/target/classes/org/gcube/datacatalogue/ckanutillibrary/shared/ex/TooManyRunningClustersException.class new file mode 100644 index 0000000000000000000000000000000000000000..1c62e48a0843b869ead08fec9f4224b7bb9c0445 GIT binary patch literal 716 zcmb`F%}(1u6ot=)5Tg(pNcbz=7^w@OQoX3!4OJu*0%{v7wGP=<6K86sI5TKwT)}hn zNmwCu(OoxvgFZ_o#I=cF0TP=oJofc`_uO;F{&V&77l2oI7GR3-$=EbXlYA(nk?G>>qvS;B+^Z~8Lo4ig2tBbQ;}m5Eh)YN@N4Z89aKoN1*qF`Hs=f3+)FY%jL|Ewe{fl-}XO3W3Rivd(`WH zIqb&q?m?H(?A-~+-tzpNS