diff --git a/.classpath b/.classpath index 4156377..ae8c41c 100644 --- a/.classpath +++ b/.classpath @@ -13,11 +13,6 @@ - - - - - @@ -26,9 +21,14 @@ + - + + + + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index db24ee7..671cad6 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -10,6 +10,6 @@ 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.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=disabled org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml index fb95c45..f4bf050 100644 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,5 +1,5 @@ - + diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a48bc..a38a4f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,21 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.1.0-SNAPSHOT] - 2022-05-18 + +**New Features** + +- [#21643] Integrated with the content-moderator-system facilities +- [#22838] Integrated the collection provided by gCat to read the service configurations +- [#23108] The Moderation facility accessible to Catalogue Editor/Admin in read only mode +- [#23197] Revised the query passed to gCat with the moderation states + ## [v1.0.3] - 2022-01-21 **Fixes** - [#22691] Share Link on private items does not work + ## [v1.0.2] - 2021-06-03 **Fixes** diff --git a/pom.xml b/pom.xml index 9034047..03861c7 100644 --- a/pom.xml +++ b/pom.xml @@ -12,8 +12,8 @@ org.gcube.datacatalogue catalogue-util-library - 1.0.3 - + 1.1.0-SNAPSHOT + Ckan utility library Utility library to retrieve users information, organizations information and so on from the ckan d4science datacatalogue @@ -31,6 +31,8 @@ UTF-8 UTF-8 2.7.0 + 1.8 + 1.8 4.4.1 2.8.11 @@ -40,7 +42,7 @@ org.gcube.distribution maven-portal-bom - 3.6.2 + 3.6.2-SNAPSHOT pom import diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/db/DBCaller.java b/src/main/java/org/gcube/datacatalogue/utillibrary/db/DBCaller.java index 1cfbb52..d276b6b 100644 --- a/src/main/java/org/gcube/datacatalogue/utillibrary/db/DBCaller.java +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/db/DBCaller.java @@ -249,8 +249,6 @@ public class DBCaller { PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, username); preparedStatement.setString(2, state); - - LOG.debug("The query is: "+preparedStatement.toString()); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCaller.java b/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCaller.java index f5624dc..f2cd002 100644 --- a/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCaller.java +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCaller.java @@ -4,28 +4,42 @@ package org.gcube.datacatalogue.utillibrary.gcat; import java.net.MalformedURLException; +import java.util.Map; import javax.ws.rs.WebApplicationException; +import javax.xml.ws.WebServiceException; +import org.gcube.datacatalogue.utillibrary.shared.GCatCatalogueConfiguration; +import org.gcube.gcat.api.configuration.CatalogueConfiguration; +import org.gcube.gcat.api.moderation.CMItemStatus; +import org.gcube.gcat.api.moderation.Moderated; +import org.gcube.gcat.client.Configuration; import org.gcube.gcat.client.Group; import org.gcube.gcat.client.Item; import org.gcube.gcat.client.Resource; import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The Class GCatCaller. * - * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) - * May 29, 2020 + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) May 29, 2020 */ public class GCatCaller { - + private String catalogueURL; - + private GCatCatalogueConfiguration catalogueConfiguration; + private static final Logger LOG = LoggerFactory.getLogger(GCatCaller.class); + + public final static String MODERATOR_ITEM_STATUS_PARAMETER = Moderated.CM_ITEM_STATUS_QUERY_PARAMETER; + public final static String MODERATOR_ITEM_ANY_STATUS_VALUE = CMItemStatus.ANY.getValue(); + + public final static String DEFAULT_SORT_VALUE = "name asc"; + /** * Instantiates a new g cat caller. * @@ -34,68 +48,7 @@ public class GCatCaller { public GCatCaller(String catalogueURL) { this.catalogueURL = catalogueURL; } - - - /** - * Gets the dataset for name. - * - * @param datasetName the dataset name - * @return the jsonValue - * @throws WebApplicationException the web application exception - * @throws MalformedURLException the malformed URL exception - */ - public String getDatasetForName(String datasetName) throws WebApplicationException, MalformedURLException { - LOG.debug("GetDatasetForName called"); - LOG.info("Get dataset for name "+datasetName+ "called"); - return new Item().read(datasetName); - } - - - /** - * Creates the dataset. - * - * @param jsonDataset the json dataset - * @param socialPost if true sends the social post - * @return the jsonValue - * @throws WebApplicationException the web application exception - * @throws MalformedURLException the malformed URL exception - */ - public String createDataset(String jsonDataset, boolean socialPost) throws WebApplicationException, MalformedURLException { - LOG.debug("Create dataset called"); - LOG.info("Calling create on: "+jsonDataset); - return new Item().create(jsonDataset,socialPost); - } - - - /** - * Adds the resource to dataset. - * - * @param datasetId the dataset id - * @param jsonValueResource the json value resource - * @return the string - * @throws MalformedURLException the malformed URL exception - */ - public String addResourceToDataset(String datasetId, String jsonValueResource) throws MalformedURLException { - LOG.debug("Create resource called"); - LOG.info("Calling create resource: "+jsonValueResource+ " for dataset id: "+datasetId); - return new Resource().create(datasetId, jsonValueResource); - } - - - /** - * Delete resource. - * - * @param datasetId the dataset id - * @param resourceId the resource id - * @throws MalformedURLException the malformed URL exception - */ - public void deleteResource(String datasetId, String resourceId) throws MalformedURLException { - LOG.debug("Delete resource called"); - LOG.info("Calling delete resource with: "+resourceId+ " for dataset id: "+datasetId); - new Resource().delete(datasetId, resourceId); - } - - + /** * Gets the catalogue URL. * @@ -105,7 +58,79 @@ public class GCatCaller { return catalogueURL; } - + /** + * Gets the dataset for name. + * + * @param datasetName the dataset name + * @return the jsonValue + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + public String getDatasetForName(String datasetName) throws WebApplicationException, MalformedURLException { + LOG.debug("getDatasetForName called"); + LOG.info("Get dataset for name '" + datasetName + "' called"); + return new Item().read(datasetName); + } + + /** + * Creates the dataset. + * + * @param jsonDataset the json dataset + * @param socialPost if true sends the social post + * @return the jsonValue + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + public String createDataset(String jsonDataset, boolean socialPost) + throws WebApplicationException, MalformedURLException { + LOG.trace("createDataset called"); + LOG.info("Calling create on: " + jsonDataset); + return new Item().create(jsonDataset, socialPost); + } + + /** + * Update dataset. + * + * @param datasetName the dataset name + * @param jsonDataset the json dataset + * @return the string + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + public String updateDataset(String datasetName, String jsonDataset) + throws WebApplicationException, MalformedURLException { + LOG.trace("updateDataset called"); + LOG.info("Calling update item with name: " + datasetName + ", on: " + jsonDataset); + return new Item().update(datasetName, jsonDataset); + } + + /** + * Adds the resource to dataset. + * + * @param datasetId the dataset id + * @param jsonValueResource the json value resource + * @return the string + * @throws MalformedURLException the malformed URL exception + */ + public String addResourceToDataset(String datasetId, String jsonValueResource) throws MalformedURLException { + LOG.trace("addResourceToDataset called"); + LOG.info("Calling create resource: " + jsonValueResource + " for dataset id: " + datasetId); + return new Resource().create(datasetId, jsonValueResource); + } + + /** + * Delete resource. + * + * @param datasetId the dataset id + * @param resourceId the resource id + * @throws MalformedURLException the malformed URL exception + */ + public void deleteResource(String datasetId, String resourceId) throws MalformedURLException { + LOG.trace("deleteResource called"); + LOG.info("Calling delete resource with: " + resourceId + " for dataset id: " + datasetId); + new Resource().delete(datasetId, resourceId); + } + /** * Creates the group. * @@ -113,27 +138,214 @@ public class GCatCaller { * @return the string * @throws MalformedURLException the malformed URL exception */ - public String createGroup(String jsonGroup) throws MalformedURLException { - LOG.debug("Create group called"); - LOG.info("Calling create group: "+jsonGroup); + public String createGroup(String jsonGroup) throws MalformedURLException { + LOG.trace("createGroup called"); + LOG.info("Calling create group: " + jsonGroup); return new Group().create(jsonGroup); } - /** * Patch dataset. * * @param datasetName the dataset name - * @param jsonObj the json obj + * @param jsonObj the json obj * @return the string * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + public String patchDataset(String datasetName, JSONObject jsonObj) + throws WebApplicationException, MalformedURLException { + LOG.trace("patchDataset called"); + LOG.info("Calling patch dataset with name: " + datasetName); + + return new Item().patch(datasetName, jsonObj.toJSONString()); + + } + + /** + * Approve item. + * + * @param datasetName the dataset name + * @param moderatorMessage the moderator message + * @return the string + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + public String approveItem(String datasetName, String moderatorMessage) + throws WebApplicationException, MalformedURLException { + LOG.trace("approveItem called"); + LOG.info("Calling approve item with name: " + datasetName + ", and msg: " + moderatorMessage); + + return new Item().approve(datasetName, moderatorMessage); + + } + + /** + * Reject item. + * + * @param datasetName the dataset name + * @param permanentlyDelete the permanently delete + * @param moderatorMessage the moderator message + * @return the string + * @throws WebServiceException the web service exception * @throws MalformedURLException the malformed URL exception */ - public String patchDataset(String datasetName, JSONObject jsonObj) throws WebApplicationException, MalformedURLException { - LOG.debug("Patch dataset called"); - LOG.info("Calling patch dataset with name: "+datasetName); - return new Item().patch(datasetName, jsonObj.toJSONString()); - + public String rejectItem(String datasetName, boolean permanentlyDelete, String moderatorMessage) + throws WebServiceException, MalformedURLException { + LOG.trace("rejectItem called"); + LOG.info("Calling reject item with name: " + datasetName + ", and msg: " + moderatorMessage); + + String toReturnMsg = new Item().reject(datasetName, moderatorMessage); + + if (permanentlyDelete) { + deleteItem(datasetName, true); + } + + return toReturnMsg; + } + + /** + * Delete item. + * + * @param datasetName the dataset name + * @param purge the purge + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + public void deleteItem(String datasetName, boolean purge) throws WebServiceException, MalformedURLException { + LOG.trace("deleteItem called"); + LOG.info("Calling delete item with name: " + datasetName + ", and purge: " + purge); + + new Item().delete(datasetName, purge); + return; + } + + /** + * Gets the list items for CM status. + * + * @param status the status + * @param limit the limit + * @param offset the offset + * @param filters the filters + * @param sortForField the sort for field + * @return the list items for CM status + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + public String getListItemsForCMStatus(CMItemStatus status, int limit, int offset, Map filters, String sortForField) + throws WebServiceException, MalformedURLException { + LOG.trace("getListItemsForCMStatus called"); + LOG.info("called getListItemsForCMStatus called with [status: " + status + "], [limit: " + limit + + "], [offset: " + offset + "], [filters: " + filters + "]"); + + Map queryParams = GCatCallerUtil.genericQueryBuilderFor(status, limit, offset, false, filters, sortForField); + + return getListItemsForQuery(queryParams); + } + + /** + * Count list items for CM status. + * + * @param status the status + * @param filters + * @return the number of items + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + public int countListItemsForCMStatus(CMItemStatus status, Map filters) + throws WebServiceException, MalformedURLException { + LOG.trace("countListItemsForCMStatus called"); + LOG.info("Calling count list items for [status: " + status + "], [filters: " + filters + "]"); + + Map queryParams = GCatCallerUtil.genericQueryBuilderFor(status, null, null, true, filters, null); + + String theCount = getListItemsForQuery(queryParams); + int count = 0; + try { + JSONParser parser = new JSONParser(); + JSONObject jsonCount = (JSONObject) parser.parse(theCount); + Long total = (Long) jsonCount.get("count"); + count = total.intValue(); + } catch (Exception e) { + LOG.warn("Size retured by gCat is not an integer, returning: " + count, e); + } + return count; + } + + /** + * Gets the list items. + * + * @param limit the limit + * @param offset the offset + * @return the list items + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + public String getListItems(int limit, int offset) throws WebServiceException, MalformedURLException { + LOG.trace("getListItems called"); + LOG.info("Calling list items with limit: " + limit + ", offset: " + offset); + + return new Item().list(limit, offset); + } + + /** + * Gets the list items for query. + * + * @param queryParams the query params + * @return the list items for query + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + public String getListItemsForQuery(Map queryParams) + throws WebServiceException, MalformedURLException { + LOG.trace("getListItemsForQuery called"); + LOG.info("Calling list items for query: " + queryParams); + + return new Item().list(queryParams); + } + + /** + * Gets the configuration. + * + * @param reload the reload + * @return the configuration + * @throws MalformedURLException + */ + public GCatCatalogueConfiguration getConfiguration(boolean reload) throws MalformedURLException { + LOG.trace("getConfiguration called"); + LOG.info("Calling get configuration with reload config: " + reload); + + if (reload || catalogueConfiguration == null) { + catalogueConfiguration = new GCatCatalogueConfiguration(); + + Configuration gCatConfig = new Configuration(); + CatalogueConfiguration gCG = gCatConfig.read(); + + catalogueConfiguration.setCkanURL(gCG.getCkanURL()); + catalogueConfiguration.setContext(gCG.getContext()); + catalogueConfiguration.setDefaultOrganization(gCG.getDefaultOrganization()); + catalogueConfiguration.setModerationEnabled(gCG.isModerationEnabled()); + catalogueConfiguration.setSocialPostEnabled(gCG.isSocialPostEnabled()); + catalogueConfiguration.setNotificationToUsersEnabled(gCG.isNotificationToUsersEnabled()); + catalogueConfiguration.setSolrURL(gCG.getSolrURL()); + catalogueConfiguration.setSupportedOrganizations(gCG.getSupportedOrganizations()); + } + LOG.info("returning gCatConfig: " + catalogueConfiguration); + return catalogueConfiguration; + } + + private static int offsetToPageNumber(int limit, int offset) { + + int pageNumber = offset; + + try { + pageNumber = offset / limit; + } catch (Exception e) { + LOG.warn("Page number error: ", e); + } + + return pageNumber; + } } diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCallerUtil.java b/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCallerUtil.java new file mode 100644 index 0000000..b7ad6fc --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/gcat/GCatCallerUtil.java @@ -0,0 +1,112 @@ +package org.gcube.datacatalogue.utillibrary.gcat; + +import java.io.InvalidObjectException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.gcube.gcat.api.moderation.CMItemStatus; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class GCatCallerUtil. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Apr 7, 2022 + */ +public class GCatCallerUtil { + + private static final Logger LOG = LoggerFactory.getLogger(GCatCallerUtil.class); + + /** + * Generic query builder for. + * + * @param status the status + * @param limit the limit + * @param offset the offset + * @param count the count + * @param filters the filters + * @return the map + */ + public static Map genericQueryBuilderFor(CMItemStatus status, Integer limit, Integer offset, + Boolean count, Map filters, String sort) { + LOG.info("genericQueryBuilderFor called with [status: " + status + "], [limit: " + limit + "], [offset: " + + offset + "], [count: " + count + "], [filters: " + filters + "]"); + + Map queryParams = new HashMap(); + + if (filters != null) { + StringBuilder queryBuilder = new StringBuilder(); + + List keySet = new ArrayList(); + keySet.addAll(filters.keySet()); + String firstKey = keySet.get(0); + queryBuilder.append(firstKey + ":" + filters.get(firstKey)); + + for (int i = 1; i < keySet.size(); i++) { + String key = keySet.get(i); + queryBuilder.append(" AND " + key + ":" + filters.get(key)); + } + queryParams.put("q", queryBuilder.toString()); + } + + if (status != null) { + queryParams.put(GCatCaller.MODERATOR_ITEM_STATUS_PARAMETER, status.getValue()); + } + + if (limit != null) { + limit = limit < 0 ? 10 : limit; + queryParams.put("limit", limit + ""); + } + if (offset != null) { + offset = offset < 0 ? 0 : offset; + queryParams.put("offset", offset + ""); + } + + if (sort != null) { + queryParams.put("sort", sort); + }else { + LOG.info("Adding defautl sort: "+GCatCaller.DEFAULT_SORT_VALUE); + queryParams.put("sort", GCatCaller.DEFAULT_SORT_VALUE); + } + + + if (count != null) { + if (count) { + queryParams.put("count", "true"); + } + } + + return queryParams; + } + + public static List toListString(String gcatListResponse) throws InvalidObjectException { + + List listData = new ArrayList(); + + if (gcatListResponse != null) { + LOG.debug("converting list {}", gcatListResponse); + JSONParser parser = new JSONParser(); + try { + JSONArray jsonArray = (JSONArray) parser.parse(gcatListResponse); + for (Object data : jsonArray) { + if (data instanceof String) { + listData.add((String) data); + } + } + } catch (ParseException e) { + LOG.error("error occurred reading " + gcatListResponse + " as JSONArray", e); + throw new InvalidObjectException(e.getMessage()); + } + } + + return listData; + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogue.java b/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogue.java index e5b90d2..5250398 100644 --- a/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogue.java +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogue.java @@ -77,12 +77,20 @@ public interface DataCatalogue { String getUriResolverUrl(); /** - * Return the manage product property. + * Return the manage product property (used in the GRSF[-ADMIN] contexts). * * @return the manage product property */ boolean isManageProductEnabled(); + /** + * Checks if is moderation enabled. + * + * @param reloadConfig the reload config from service + * @return true, if is moderation enabled + */ + boolean isModerationEnabled(boolean reloadConfig); + /** * Return the catalogue portlet for this context(i.e. scope) * @@ -332,6 +340,7 @@ public interface DataCatalogue { * @param organizationName the organization name * @param username the username * @return String the id of the resource on success, null otherwise + * @throws Exception the exception */ String addResourceToDataset(ResourceBean resourceBean, String organizationName, String username) throws Exception; @@ -339,7 +348,7 @@ public interface DataCatalogue { * Remove the resource with id resourceId from dataset in which it is. * * @param resourceId the resource id - * @param username the username + * @param username the username * @return true on success, false otherwise. * @throws Exception the exception */ @@ -401,6 +410,15 @@ public interface DataCatalogue { boolean patchProductCustomFields(String productId, String username, Map> customFieldsToChange, boolean removeOld); + /** + * Refresh dataset. + * + * @param datasetName the dataset name + * @return the string + * @throws Exception the exception + */ + String refreshDataset(String datasetName) throws Exception; + /** * Patch a product with product id productId by using the couples in * customFieldsToChange. NOTE: only the specified custom fields will be changed. @@ -408,9 +426,9 @@ public interface DataCatalogue { * false, the new values are added at the end of the list. Otherwise they are * lost. * - * @param productId the product id - * @param customFieldsToChange the custom fields to change - * @param removeOld the remove old + * @param username the username + * @param sourceOrganization the source organization + * @param currentRole the current role * @return true, if successful */ // boolean patchProductCustomFields(String productId, Map> customFieldsToChange, diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogueImpl.java b/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogueImpl.java index f4b60bc..a5e664e 100644 --- a/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogueImpl.java +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/server/DataCatalogueImpl.java @@ -3,6 +3,8 @@ package org.gcube.datacatalogue.utillibrary.server; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import java.io.InvalidObjectException; +import java.net.MalformedURLException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; @@ -16,6 +18,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import javax.xml.ws.WebServiceException; + import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; @@ -32,12 +36,16 @@ import org.gcube.datacatalogue.utillibrary.ckan.MarshUnmarshCkanObject; import org.gcube.datacatalogue.utillibrary.ckan.MarshUnmarshCkanObject.METHOD; import org.gcube.datacatalogue.utillibrary.db.DBCaller; import org.gcube.datacatalogue.utillibrary.gcat.GCatCaller; +import org.gcube.datacatalogue.utillibrary.gcat.GCatCallerUtil; import org.gcube.datacatalogue.utillibrary.server.DataCatalogueRunningCluster.ACCESS_LEVEL_TO_CATALOGUE_PORTLET; +import org.gcube.datacatalogue.utillibrary.server.cms.CatalogueContentModeratorSystem; +import org.gcube.datacatalogue.utillibrary.server.cms.DataCatalogueCMSImpl; import org.gcube.datacatalogue.utillibrary.server.utils.CKANConveter; import org.gcube.datacatalogue.utillibrary.server.utils.CatalogueUtilMethods; import org.gcube.datacatalogue.utillibrary.server.utils.GCubeUtils; import org.gcube.datacatalogue.utillibrary.server.utils.GcubeContext; import org.gcube.datacatalogue.utillibrary.server.utils.url.EntityContext; +import org.gcube.datacatalogue.utillibrary.shared.GCatCatalogueConfiguration; import org.gcube.datacatalogue.utillibrary.shared.LandingPages; import org.gcube.datacatalogue.utillibrary.shared.ResourceBean; import org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg; @@ -56,12 +64,12 @@ import org.json.simple.parser.JSONParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * This is the Ckan Utils implementation class. * * revisited by - * @author Francesco Mangiacrapa at ISTI-CNR + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ @@ -80,35 +88,25 @@ public class DataCatalogueImpl implements DataCatalogue { private String CKAN_TOKEN_SYS; private String CKAN_EMAIL; private String URI_RESOLVER_URL; - private boolean MANAGE_PRODUCT_BUTTON; + private boolean MANAGE_GRSF_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 ExtendCkanClient ckanCaller; - // hashmap for ckan api keys private ConcurrentHashMap apiKeysMap; - - //http ckan caller - //private DirectCkanCaller directCkanCaller; //is not needed anymore? - // apikey bean expires after X minutes in the above map private static final int EXPIRE_KEY_TIME = 60 * 60 * 1000; + private DataCatalogueCMSImpl dataCatalogueCMSImpl = null; /** * The ckan catalogue url and database will be discovered in this scope. @@ -116,7 +114,7 @@ public class DataCatalogueImpl implements DataCatalogue { * @param scope the scope * @throws Exception if unable to find datacatalogue info */ - public DataCatalogueImpl(String scope) throws Exception{ + public DataCatalogueImpl(String scope) throws Exception { DataCatalogueRunningCluster runningInstance = new DataCatalogueRunningCluster(scope); @@ -133,19 +131,20 @@ public class DataCatalogueImpl implements DataCatalogue { CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0).trim(); PORTLET_URL_FOR_SCOPE = runningInstance.getPortletUrl().trim(); mapAccessURLToCatalogue = runningInstance.getMapAccessURLToCatalogue(); - MANAGE_PRODUCT_BUTTON = runningInstance.isManageProductEnabled(); + MANAGE_GRSF_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); - + 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 ExtendCkanClient(CKAN_CATALOGUE_URL); - //directCkanCaller = new DirectCkanCaller(CKAN_CATALOGUE_URL); //is not needed anymore? + // directCkanCaller = new DirectCkanCaller(CKAN_CATALOGUE_URL); //is not needed + // anymore? // init map apiKeysMap = new ConcurrentHashMap(); // save the context @@ -153,62 +152,90 @@ public class DataCatalogueImpl implements DataCatalogue { // extended roles extendRoleInOrganization = runningInstance.getExtendRoleInOrganization(); } - + /** * The ckan catalogue url and database will be discovered in this scope. * - * @param scope the scope + * @param scope the scope * @param sysAuthentication if true perform the sys authentication * @throws Exception if unable to find datacatalogue info */ - public DataCatalogueImpl(String scope, boolean sysAuthentication) throws Exception{ + public DataCatalogueImpl(String scope, boolean sysAuthentication) throws Exception { this(scope); - - if(sysAuthentication) + + if (sysAuthentication) ckanCaller = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS); } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getCatalogueUrl() + + /** + * Gets the catalogue url. + * + * @return the catalogue url + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getCatalogueUrl() */ @Override public String getCatalogueUrl() { return CKAN_CATALOGUE_URL; } - - /* (non-Javadoc) + /** + * Gets the portlet url. + * + * @return the portlet url + */ + /* + * (non-Javadoc) + * * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getPortletUrl() */ @Override public String getPortletUrl() { - //PATCHED By Francesco + // 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); + + 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 + // 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 + "/"; + } 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); + 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; } } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#findLicenseIdByLicenseTitle(java.lang.String) + /** + * Find license id by license title. + * + * @param chosenLicense the chosen license + * @return the string + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * findLicenseIdByLicenseTitle(java.lang.String) */ @Override public String findLicenseIdByLicenseTitle(String chosenLicense) { @@ -217,19 +244,27 @@ public class DataCatalogueImpl implements DataCatalogue { // checks checkNotNull(chosenLicense); - //retrieve the list of available licenses + // retrieve the list of available licenses List licenses = ckanCaller.getLicenseList(); for (CkanLicense ckanLicense : licenses) { - if(ckanLicense.getTitle().equals(chosenLicense)) + if (ckanLicense.getTitle().equals(chosenLicense)) return ckanLicense.getId(); } return null; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getLicenseTitles() + /** + * Gets the license titles. + * + * @return the license titles + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getLicenseTitles() */ @Override public List getLicenseTitles() { @@ -248,7 +283,14 @@ public class DataCatalogueImpl implements DataCatalogue { return result; } - /* (non-Javadoc) + /** + * Gets the licenses. + * + * @return the licenses + */ + /* + * (non-Javadoc) + * * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getLicenses() */ @Override @@ -258,13 +300,23 @@ public class DataCatalogueImpl implements DataCatalogue { return ckanCaller.getLicenseList(); } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getDataset(java.lang.String, java.lang.String) + /** + * Gets the dataset. + * + * @param datasetIdOrName the dataset id or name + * @param username the username + * @return the dataset + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getDataset(java.lang + * .String, java.lang.String) */ @Override public CkanDataset getDataset(String datasetIdOrName, String username) { - LOG.info("Called getDataset with id or name" + datasetIdOrName+ " and username: "+username); + LOG.info("Called getDataset with id or name" + datasetIdOrName + " and username: " + username); // checks checkNotNull(datasetIdOrName); @@ -288,10 +340,31 @@ public class DataCatalogueImpl implements DataCatalogue { return null; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getUnencryptedUrlFromDatasetIdOrName(java.lang.String) + /** + * Gets the catalogue content moderator system. + * + * @return the catalogue content moderator + */ + public CatalogueContentModeratorSystem getCatalogueContentModerator() { + if (dataCatalogueCMSImpl == null) { + dataCatalogueCMSImpl = new DataCatalogueCMSImpl(CONTEXT, gCatCaller); + } + + return dataCatalogueCMSImpl; + } + + /** + * Gets the unencrypted url from dataset id or name. + * + * @param datasetIdOrName the dataset id or name + * @return the unencrypted url from dataset id or name + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getUnencryptedUrlFromDatasetIdOrName(java.lang.String) */ @Override public String getUnencryptedUrlFromDatasetIdOrName(String datasetIdOrName) { @@ -323,9 +396,18 @@ public class DataCatalogueImpl implements DataCatalogue { return url; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getUserRoleByGroup(java.lang.String) + /** + * Gets the user role by group. + * + * @param username the username + * @return the user role by group + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getUserRoleByGroup( + * java.lang.String) */ @Override public Map> getUserRoleByGroup(String username) { @@ -357,9 +439,18 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getUserRoleByOrganization(java.lang.String) + + /** + * Gets the user role by organization. + * + * @param username the username + * @return the user role by organization + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getUserRoleByOrganization(java.lang.String) */ @Override public Map> getUserRoleByOrganization(String username) { @@ -391,14 +482,13 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - - + /** * Retrieve an url for the tuple scope, entity, entity name. * - * @param context the context + * @param context the context * @param entityContext the entity context - * @param entityName the entity name + * @param entityName the entity name * @return the url for product */ private String getUrlForProduct(String context, EntityContext entityContext, String entityName) { @@ -431,9 +521,18 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getLandingPages() + + /** + * Gets the landing pages. + * + * @return the landing pages + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getLandingPages() */ @Override public LandingPages getLandingPages() throws Exception { @@ -446,8 +545,16 @@ public class DataCatalogueImpl implements DataCatalogue { return landingPages; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getUriResolverUrl() + /** + * Gets the uri resolver url. + * + * @return the uri resolver url + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getUriResolverUrl() */ @Override public String getUriResolverUrl() { @@ -461,34 +568,81 @@ public class DataCatalogueImpl implements DataCatalogue { */ @Override public boolean isManageProductEnabled() { - return MANAGE_PRODUCT_BUTTON; + return MANAGE_GRSF_PRODUCT_BUTTON; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getGroupByName(java.lang.String) + + /** + * Checks if is moderation enabled. + * + * @param reloadConfig the reload config + * @return true, if is moderation enabled + */ + @Override + public boolean isModerationEnabled(boolean reloadConfig) { + try { + LOG.info("Called isModerationEnabled with reloadConfig: " + reloadConfig); + GCatCatalogueConfiguration config = gCatCaller.getConfiguration(reloadConfig); + return config.isModerationEnabled(); + } catch (Exception e) { + LOG.error("Error occurred on checking if moderation is enabled. Returning false", e); + return false; + } + } + + /** + * Gets the group by name. + * + * @param name the name + * @return the group by name + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getGroupByName(java. + * lang.String) */ @Override public CkanGroup getGroupByName(String name) { String ckanName = CatalogueUtilMethods.fromGroupTitleToName(name); - try{ + try { return ckanCaller.getGroup(ckanName); - }catch(Exception e){ + } catch (Exception e) { LOG.error("Failed to retrieve the group with name" + name, e); } return null; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#isNotificationToUsersEnabled() + /** + * Checks if is notification to users enabled. + * + * @return true, if is notification to users enabled + * + * YOU NEED TO USE gCat + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * isNotificationToUsersEnabled() */ @Override + @Deprecated public boolean isNotificationToUsersEnabled() { return ALERT_USERS_ON_POST_CREATION; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationsByUser(java.lang.String) + /** + * Gets the organizations by user. + * + * @param username the username + * @return the organizations by user + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getOrganizationsByUser(java.lang.String) */ @Override public List getOrganizationsByUser(String username) { @@ -518,8 +672,18 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getGroupsByUser(java.lang.String) + /** + * Gets the groups by user. + * + * @param username the username + * @return the groups by user + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getGroupsByUser(java + * .lang.String) */ @Override public List getGroupsByUser(String username) { @@ -548,8 +712,17 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationsIds() + /** + * Gets the organizations ids. + * + * @return the organizations ids + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationsIds( + * ) */ @Override public List getOrganizationsIds() { @@ -565,8 +738,16 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationsNames() + /** + * Gets the organizations names. + * + * @return the organizations names + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getOrganizationsNames() */ @Override public List getOrganizationsNames() { @@ -582,8 +763,17 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationsNamesByUser(java.lang.String) + /** + * Gets the organizations names by user. + * + * @param username the username + * @return the organizations names by user + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getOrganizationsNamesByUser(java.lang.String) */ @Override public List getOrganizationsNamesByUser(String username) { @@ -607,8 +797,18 @@ public class DataCatalogueImpl implements DataCatalogue { } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getRoleOfUserInOrganization(java.lang.String, java.lang.String) + /** + * Gets the role of user in organization. + * + * @param username the username + * @param orgName the org name + * @return the role of user in organization + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getRoleOfUserInOrganization(java.lang.String, java.lang.String) */ @Override public String getRoleOfUserInOrganization(String username, String orgName) { @@ -635,8 +835,7 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - - + /** * Check if the user is valid by checking if its API_KEY is present into DB. * @@ -695,9 +894,18 @@ public class DataCatalogueImpl implements DataCatalogue { return null; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#existProductWithNameOrId(java.lang.String) + + /** + * Exist product with name or id. + * + * @param nameOrId the name or id + * @return true, if successful + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * existProductWithNameOrId(java.lang.String) */ @Override public boolean existProductWithNameOrId(String nameOrId) { @@ -715,8 +923,17 @@ public class DataCatalogueImpl implements DataCatalogue { } } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationByIdOrName(java.lang.String) + /** + * Gets the organization by id or name. + * + * @param idOrName the id or name + * @return the organization by id or name + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getOrganizationByIdOrName(java.lang.String) */ @Override public CkanOrganization getOrganizationByIdOrName(String idOrName) { @@ -739,10 +956,10 @@ public class DataCatalogueImpl implements DataCatalogue { * Check if the user has this role into the organization/group with * groupOrOrganization name. * - * @param ckanUsername the ckan username - * @param groupOrOrganization the group or organization + * @param ckanUsername the ckan username + * @param groupOrOrganization the group or organization * @param correspondentRoleToCheck the correspondent role to check - * @param group the group + * @param group the group * @return true if he has the role, false otherwise * @throws Exception the exception */ @@ -768,8 +985,7 @@ public class DataCatalogueImpl implements DataCatalogue { return false; } - - + /** * Just check if the group exists. * @@ -791,10 +1007,19 @@ public class DataCatalogueImpl implements DataCatalogue { return toReturn; } - - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getParentGroups(java.lang.String, java.lang.String) + /** + * Gets the parent groups. + * + * @param groupName the group name + * @param apiKey the api key + * @return the parent groups + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getParentGroups(java + * .lang.String, java.lang.String) */ @Override public List getParentGroups(String groupName, String apiKey) { @@ -802,18 +1027,27 @@ public class DataCatalogueImpl implements DataCatalogue { checkNotNull(groupName); checkNotNull(apiKey); - try{ + try { ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, apiKey); return client.getGroup(groupName).getGroups(); - }catch(Exception e){ + } catch (Exception e) { LOG.error("Something went wrong, returning null", e); } return null; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getOrganizationByName(java.lang.String) + + /** + * Gets the organization by name. + * + * @param name the name + * @return the organization by name + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getOrganizationByName(java.lang.String) */ @Override public CkanOrganization getOrganizationByName(String name) { @@ -821,19 +1055,38 @@ public class DataCatalogueImpl implements DataCatalogue { checkNotNull(name); String ckanName = name.toLowerCase(); - try{ + try { return ckanCaller.getOrganization(ckanName); - }catch(Exception e){ - LOG.warn("Failed to retrieve the organization with name " +name+ " on the ckan: "+ckanCaller.getCatalogUrl(), e); + } catch (Exception e) { + LOG.warn("Failed to retrieve the organization with name " + name + " on the ckan: " + + ckanCaller.getCatalogUrl(), e); } return null; } - - - - + + /** + * Perform query for items. + * + * @param queryParameters the query parameters + * @return the list + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + public List performQueryForItems(Map queryParameters) + throws WebServiceException, MalformedURLException { + checkNotNull(queryParameters); + String results = gCatCaller.getListItemsForQuery(queryParameters); + List listData = null; + try { + listData = GCatCallerUtil.toListString(results); + } catch (InvalidObjectException e) { + LOG.warn("Error occurred on reading response from gCat, returning null"); + } + return listData; + } + /** * ***************************************************************************** * @@ -843,18 +1096,18 @@ public class DataCatalogueImpl implements DataCatalogue { * * *****************************************************************************. * - * @param username the username - * @param organizationName the organization name + * @param username the username + * @param organizationName the organization name * @param correspondentRoleToCheck the correspondent role to check * @return true, if successful */ - - + @Override public boolean checkRoleIntoOrganization(String username, String organizationName, RolesCkanGroupOrOrg correspondentRoleToCheck) { - LOG.debug("Request for checking if " + username + " into organization " + organizationName + " has role " + correspondentRoleToCheck); + LOG.debug("Request for checking if " + username + " into organization " + organizationName + " has role " + + correspondentRoleToCheck); // checks checkNotNull(username); @@ -866,17 +1119,19 @@ public class DataCatalogueImpl implements DataCatalogue { // convert ckan username String ckanUsername = CatalogueUtilMethods.fromUsernameToCKanUsername(username); - // check if this role is already present in ckan for this user within the organization + // check if this role is already present in ckan for this user within the + // organization String organizationNameToCheck = organizationName.toLowerCase(); - try{ - boolean alreadyPresent = isRoleAlreadySet(ckanUsername, organizationNameToCheck, correspondentRoleToCheck, false); + try { + boolean alreadyPresent = isRoleAlreadySet(ckanUsername, organizationNameToCheck, correspondentRoleToCheck, + false); - if(alreadyPresent) + if (alreadyPresent) return true; // just return - else{ + else { - //TODO PASS by GCAT? + // TODO PASS by GCAT? // we need to use the APIs to make it String path = "/api/3/action/organization_member_create"; @@ -887,34 +1142,48 @@ public class DataCatalogueImpl implements DataCatalogue { LOG.debug("API request for organization membership is going to be " + obj.toJSONString()); - - try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { HttpPost request = new HttpPost(CKAN_CATALOGUE_URL + path); request.addHeader("Authorization", CKAN_TOKEN_SYS); // sys token StringEntity params = new StringEntity(obj.toJSONString()); request.setEntity(params); HttpResponse response = httpClient.execute(request); - LOG.debug("Response code is " + response.getStatusLine().getStatusCode() + " and response message is " + response.getStatusLine().getReasonPhrase()); + LOG.debug("Response code is " + response.getStatusLine().getStatusCode() + + " and response message is " + response.getStatusLine().getReasonPhrase()); return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK; - }catch (Exception ex) { + } catch (Exception ex) { LOG.error("Error while trying to change the role for this user ", ex); } } - }catch (Exception ex) { + } catch (Exception ex) { LOG.error("Unable to check if this role was already set, please check your parameters! ", ex); } return false; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#checkRoleIntoGroup(java.lang.String, java.lang.String, org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg) + + /** + * Check role into group. + * + * @param username the username + * @param groupName the group name + * @param correspondentRoleToCheck the correspondent role to check + * @return true, if successful + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#checkRoleIntoGroup( + * java.lang.String, java.lang.String, + * org.gcube.datacatalogue.utillibrary.shared.RolesCkanGroupOrOrg) */ @Override public boolean checkRoleIntoGroup(String username, String groupName, RolesCkanGroupOrOrg correspondentRoleToCheck) { - LOG.debug("Request for checking if " + username + " into group " + groupName + " has role " + correspondentRoleToCheck); + LOG.debug("Request for checking if " + username + " into group " + groupName + " has role " + + correspondentRoleToCheck); // checks checkNotNull(username); @@ -929,12 +1198,12 @@ public class DataCatalogueImpl implements DataCatalogue { // check if this role is already present in ckan for this user within the group String groupNameToCheck = CatalogueUtilMethods.fromGroupTitleToName(groupName); - try{ + try { boolean alreadyPresent = isRoleAlreadySet(ckanUsername, groupNameToCheck, correspondentRoleToCheck, true); - if(alreadyPresent) + if (alreadyPresent) return true; // just return - else{ + else { // we need to use the apis to make it String path = "/api/3/action/group_member_create"; @@ -946,82 +1215,164 @@ public class DataCatalogueImpl implements DataCatalogue { LOG.debug("API request for organization membership is going to be " + obj.toJSONString()); - try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { HttpPost request = new HttpPost(CKAN_CATALOGUE_URL + path); request.addHeader("Authorization", CKAN_TOKEN_SYS); // sys token StringEntity params = new StringEntity(obj.toJSONString()); request.setEntity(params); HttpResponse response = httpClient.execute(request); - LOG.debug("Response code is " + response.getStatusLine().getStatusCode() + " and response message is " + response.getStatusLine().getReasonPhrase()); + LOG.debug("Response code is " + response.getStatusLine().getStatusCode() + + " and response message is " + response.getStatusLine().getReasonPhrase()); return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK; - }catch (Exception ex) { + } catch (Exception ex) { LOG.error("Error while trying to change the role for this user ", ex); } } - }catch (Exception ex) { + } catch (Exception ex) { LOG.error("Unable to check if this role was already set, please check your parameters! ", ex); } return false; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#createCkanDatasetMultipleCustomFields(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long, java.lang.String, java.lang.String, java.util.List, java.util.Map, java.util.List, boolean, boolean, boolean) + + /** + * Creates the ckan dataset multiple custom fields. + * + * @param username the username + * @param title the title + * @param name the name + * @param organizationName the organization name + * @param author the author + * @param authorMail the author mail + * @param maintainer the maintainer + * @param maintainerMail the maintainer mail + * @param version the version + * @param description the description + * @param licenseId the license id + * @param tags the tags + * @param customFieldsMultiple the custom fields multiple + * @param resources the resources + * @param setPublic the set public + * @param setSearchable the set searchable + * @param socialPost the social post + * @return the string + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * createCkanDatasetMultipleCustomFields(java.lang.String, java.lang.String, + * java.lang.String, java.lang.String, java.lang.String, java.lang.String, + * java.lang.String, java.lang.String, long, java.lang.String, java.lang.String, + * java.util.List, java.util.Map, java.util.List, boolean, boolean, boolean) */ @Override - public String createCkanDatasetMultipleCustomFields(String username, String title, String name, String organizationName, - String author, String authorMail, String maintainer, String maintainerMail, long version, - String description, String licenseId, List tags, Map> customFieldsMultiple, - List resources, boolean setPublic, boolean setSearchable, boolean socialPost) throws Exception { + public String createCkanDatasetMultipleCustomFields(String username, String title, String name, + String organizationName, String author, String authorMail, String maintainer, String maintainerMail, + long version, String description, String licenseId, List tags, + Map> customFieldsMultiple, List resources, boolean setPublic, + boolean setSearchable, boolean socialPost) throws Exception { LOG.info("Called createCkanDatasetMultipleCustomFields"); - + // checks (minimum) checkNotNull(username); - //checkNotNull(organizationNameOrId); - //checkArgument(!organizationNameOrId.isEmpty()); - checkArgument(!(title == null && name == null || title.isEmpty() && name.isEmpty()), "Name and Title cannot be empty/null at the same time!"); - + // checkNotNull(organizationNameOrId); + // checkArgument(!organizationNameOrId.isEmpty()); + checkArgument(!(title == null && name == null || title.isEmpty() && name.isEmpty()), + "Name and Title cannot be empty/null at the same time!"); + GcubeContext gcubeContext = null; try { - - gcubeContext = GCubeUtils.detectTheOrgNameContexts(organizationName, username, true); - String toPassOrganizationToGcat = null; //Not needed to pass this information to gCat, never. + gcubeContext = GCubeUtils.detectAndSetTheOrgNameContext(organizationName, username, true); + + String toPassOrganizationToGcat = null; // Not needed to pass this information to gCat, never. // String ckanUsername = getUserFromApiKey(apiKey).getName(); - LOG.debug("The visibility parameter passed is (isPublic): "+setPublic); - CkanDataset dataset = CKANConveter.toCkanDataset(ckanCaller, username, title, name, toPassOrganizationToGcat, author, authorMail, - maintainer, maintainerMail, version, description, licenseId, tags, null, customFieldsMultiple, - resources, setPublic, setSearchable); - - LOG.debug("The isPriv property into dataset is: "+dataset.isPriv()); + LOG.debug("The visibility parameter passed is (isPublic): " + setPublic); + CkanDataset dataset = CKANConveter.toCkanDataset(ckanCaller, username, title, name, + toPassOrganizationToGcat, author, authorMail, maintainer, maintainerMail, version, description, + licenseId, tags, null, customFieldsMultiple, resources, setPublic, setSearchable); + + LOG.debug("The isPriv property into dataset is: " + dataset.isPriv()); // trying to create by gCat - String jsonValueDataset = MarshUnmarshCkanObject.toJsonValueDataset(dataset,METHOD.TO_CREATE); + String jsonValueDataset = MarshUnmarshCkanObject.toJsonValueDataset(dataset, METHOD.TO_CREATE); LOG.info("Serialized dataset is: " + jsonValueDataset); - jsonValueDataset = gCatCaller.createDataset(jsonValueDataset,socialPost); + jsonValueDataset = gCatCaller.createDataset(jsonValueDataset, socialPost); LOG.debug("Created dataset is: " + jsonValueDataset); - - if(jsonValueDataset != null){ - CkanDataset toCkanDataset = MarshUnmarshCkanObject.toCkanDataset(jsonValueDataset,METHOD.TO_READ); + + if (jsonValueDataset != null) { + CkanDataset toCkanDataset = MarshUnmarshCkanObject.toCkanDataset(jsonValueDataset, METHOD.TO_READ); LOG.info("Dataset with name " + toCkanDataset.getName() + " has been created correctly"); return toCkanDataset.getId(); } - }catch (Exception e) { + } catch (Exception e) { LOG.error("Error on creating the dataset: ", e); throw e; - }finally { - - if(gcubeContext!=null) + } finally { + + if (gcubeContext != null) GCubeUtils.revertToSourceContext(gcubeContext); } return null; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#patchFieldsForDataset(java.lang.String, java.util.Map) + /** + * Refresh dataset. + * + * @param datasetName the dataset name + * @return the string + * @throws Exception the exception + */ + @Override + public String refreshDataset(String datasetName) throws Exception { + LOG.info("Called refreshDataset"); + + checkNotNull(datasetName); + GcubeContext gcubeContext = null; + try { + + // is required? + // gcubeContext = GCubeUtils.detectAndSetTheOrgNameContext(organizationName, + // username, true); + + String jsonDataset = gCatCaller.getDatasetForName(datasetName); + jsonDataset = gCatCaller.updateDataset(datasetName, jsonDataset); + LOG.debug("Updated dataset is: " + jsonDataset); + + if (jsonDataset != null) { + CkanDataset toCkanDataset = MarshUnmarshCkanObject.toCkanDataset(jsonDataset, METHOD.TO_READ); + LOG.info("Dataset with name " + toCkanDataset.getName() + " has been updated correctly"); + return toCkanDataset.getId(); + } + } catch (Exception e) { + LOG.error("Error on updatating the dataset: ", e); + throw e; + } finally { + + if (gcubeContext != null) + GCubeUtils.revertToSourceContext(gcubeContext); + } + + return null; + } + + /** + * Patch fields for dataset. + * + * @param datasetIdOrName the dataset id or name + * @param mapFields the map fields + * @return true, if successful + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * patchFieldsForDataset(java.lang.String, java.util.Map) */ @Override public boolean patchFieldsForDataset(String datasetIdOrName, Map mapFields) throws Exception { @@ -1031,15 +1382,15 @@ public class DataCatalogueImpl implements DataCatalogue { checkNotNull(mapFields); try { - + CkanDataset dataset = ckanCaller.getDataset(datasetIdOrName); String datasetId = dataset.getId(); - + JSONObject jsonObj = new JSONObject(); for (String key : mapFields.keySet()) { jsonObj.put(key, mapFields.get(key)); } - + jsonObj.put("id", datasetId); LOG.debug("Json Dataset is: " + jsonObj); @@ -1053,8 +1404,19 @@ public class DataCatalogueImpl implements DataCatalogue { } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#setSearchableFieldForDataset(java.lang.String, boolean) + /** + * Sets the searchable field for dataset. + * + * @param datasetId the dataset id + * @param searchable the searchable + * @return true, if successful + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * setSearchableFieldForDataset(java.lang.String, boolean) */ @Override public boolean setSearchableFieldForDataset(String datasetId, boolean searchable) throws Exception { @@ -1079,36 +1441,49 @@ public class DataCatalogueImpl implements DataCatalogue { } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#addResourceToDataset(org.gcube.datacatalogue.utillibrary.shared.ResourceBean) + /** + * Adds the resource to dataset. + * + * @param resourceBean the resource bean + * @param organizationName the organization name + * @param username the username + * @return the string + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#addResourceToDataset + * (org.gcube.datacatalogue.utillibrary.shared.ResourceBean) */ @Override - public String addResourceToDataset(ResourceBean resourceBean, String organizationName, String username) throws Exception { + public String addResourceToDataset(ResourceBean resourceBean, String organizationName, String username) + throws Exception { LOG.info("Called addResourceToDataset by this bean " + resourceBean); // checks checkNotNull(resourceBean); checkNotNull(resourceBean.getUrl()); - - //Commented since #21259 - /*boolean isAccessibleURL = false; - try { - isAccessibleURL = CatalogueUtilMethods.resourceExists(resourceBean.getUrl()); - } catch (Exception e) { - throw new Exception("It seems the resource at this url " + resourceBean.getUrl()+" is not reachable. Error: "+e.getMessage()); - } - if(!isAccessibleURL){ - throw new Exception("It seems there is no resource at this url " + resourceBean.getUrl()); - }*/ + // Commented since #21259 + /* + * boolean isAccessibleURL = false; try { isAccessibleURL = + * CatalogueUtilMethods.resourceExists(resourceBean.getUrl()); } catch + * (Exception e) { throw new Exception("It seems the resource at this url " + + * resourceBean.getUrl()+" is not reachable. Error: "+e.getMessage()); } + * + * if(!isAccessibleURL){ throw new + * Exception("It seems there is no resource at this url " + + * resourceBean.getUrl()); } + */ GcubeContext gcubeContext = null; try { - - //Switch the context if needed - gcubeContext = GCubeUtils.detectTheOrgNameContexts(organizationName, username, true); - + + // Switch the context if needed + gcubeContext = GCubeUtils.detectAndSetTheOrgNameContext(organizationName, username, true); + CkanResource resource = CKANConveter.toCkanResource(CKAN_CATALOGUE_URL, resourceBean); String jsonValueResource = MarshUnmarshCkanObject.toJsonValueResource(resource, METHOD.TO_CREATE); @@ -1119,22 +1494,34 @@ public class DataCatalogueImpl implements DataCatalogue { CkanResource createdRes = MarshUnmarshCkanObject.toCkanResource(jsonValueResource); if (createdRes != null) { - LOG.info("Resource with id: " + createdRes.getId() + ", name: "+createdRes.getName()+" added correclty"); + LOG.info("Resource with id: " + createdRes.getId() + ", name: " + createdRes.getName() + + " added correclty"); return createdRes.getId(); } - }catch (Exception e) { - LOG.error("Unable to add the resource "+resourceBean, e); - }finally { - //revert the context if needed - if(gcubeContext!=null) + } catch (Exception e) { + LOG.error("Unable to add the resource " + resourceBean, e); + } finally { + // revert the context if needed + if (gcubeContext != null) GCubeUtils.revertToSourceContext(gcubeContext); } return null; } - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#deleteResourceFromDataset(java.lang.String) + /** + * Delete resource from dataset. + * + * @param resourceId the resource id + * @param username the username + * @return true, if successful + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * deleteResourceFromDataset(java.lang.String) */ @Override public boolean deleteResourceFromDataset(String resourceId, String username) throws Exception { @@ -1145,32 +1532,45 @@ public class DataCatalogueImpl implements DataCatalogue { checkArgument(!resourceId.isEmpty()); GcubeContext gcubeContext = null; - try{ + try { CkanResource theResource = ckanCaller.getResource(resourceId); - + CkanDataset theDataset = getDataset(theResource.getPackageId(), username); - - //Switch the context if needed - gcubeContext = GCubeUtils.detectTheOrgNameContexts(theDataset.getOrganization().getName(), username, true); - + + // Switch the context if needed + gcubeContext = GCubeUtils.detectAndSetTheOrgNameContext(theDataset.getOrganization().getName(), username, + true); + gCatCaller.deleteResource(theResource.getPackageId(), resourceId); LOG.info("Resource with id: " + resourceId + " deleted correclty"); return true; - }catch(Exception e){ + } catch (Exception e) { LOG.error("Unable to delete resource whose id is " + resourceId, e); - }finally { - //revert the context if needed - if(gcubeContext!=null) + } finally { + // revert the context if needed + if (gcubeContext != null) GCubeUtils.revertToSourceContext(gcubeContext); } return false; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#createGroup(java.lang.String, java.lang.String, java.lang.String) + /** + * Creates the group. + * + * @param name the name + * @param title the title + * @param description the description + * @return the ckan group + * @throws Exception the exception + */ + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#createGroup(java. + * lang.String, java.lang.String, java.lang.String) */ @Override public CkanGroup createGroup(String name, String title, String description) throws Exception { @@ -1181,12 +1581,13 @@ public class DataCatalogueImpl implements DataCatalogue { // check if it exists CkanGroup toCreate = null; - LOG.debug("Request for creating group with name " + name + " title " + title + " and description " + description); + LOG.debug( + "Request for creating group with name " + name + " title " + title + " and description " + description); String normalizedName = CatalogueUtilMethods.fromGroupTitleToName(name); - if((toCreate = groupExists(name))!= null) + if ((toCreate = groupExists(name)) != null) return toCreate; - else{ - try{ + else { + try { CkanGroup group = new CkanGroup(normalizedName); group.setTitle(title); @@ -1194,22 +1595,30 @@ public class DataCatalogueImpl implements DataCatalogue { group.setDescription(description); String jsonValueGroup = MarshUnmarshCkanObject.toJsonValueGroup(group); LOG.trace("Serialized group is: " + jsonValueGroup); - + String theGroup = gCatCaller.createGroup(jsonValueGroup); toCreate = MarshUnmarshCkanObject.toCkanGroup(theGroup); - LOG.info("Created the group with id: " + toCreate.getId() + ", name: "+toCreate.getName()); + LOG.info("Created the group with id: " + toCreate.getId() + ", name: " + toCreate.getName()); - }catch(JackanException je){ + } catch (JackanException je) { LOG.error("Unable to create such group", je); } } return toCreate; } - - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#getRolesAndUsersGroup(java.lang.String) + + /** + * Gets the roles and users group. + * + * @param groupName the group name + * @return the roles and users group + */ + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * getRolesAndUsersGroup(java.lang.String) */ @Override public Map> getRolesAndUsersGroup(String groupName) { @@ -1222,14 +1631,14 @@ public class DataCatalogueImpl implements DataCatalogue { CkanGroup group = ckanCaller.getGroup(groupNameToCheck); - if(group != null){ + if (group != null) { capacityAndUsers = new HashMap>(); List users = group.getUsers(); for (CkanUser ckanUser : users) { List listUsers; - if(capacityAndUsers.containsKey(RolesCkanGroupOrOrg.convertFromCapacity(ckanUser.getCapacity()))){ + if (capacityAndUsers.containsKey(RolesCkanGroupOrOrg.convertFromCapacity(ckanUser.getCapacity()))) { listUsers = capacityAndUsers.get(RolesCkanGroupOrOrg.convertFromCapacity(ckanUser.getCapacity())); - }else + } else listUsers = new ArrayList(); listUsers.add(ckanUser.getName()); @@ -1241,22 +1650,45 @@ public class DataCatalogueImpl implements DataCatalogue { } return capacityAndUsers; } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#assignDatasetToGroup(java.lang.String, java.lang.String) + /* + * (non-Javadoc) + * + * @see + * org.gcube.datacatalogue.utillibrary.server.DataCatalogue#assignDatasetToGroup + * (java.lang.String, java.lang.String) */ - //TODO HAS TO BE REVISITED by gCAT + /** + * Assign dataset to group. + * + * @param groupNameOrId the group name or id + * @param datasetNameOrId the dataset name or id + * @return true, if successful + */ + // TODO HAS TO BE REVISITED by gCAT @Override public boolean assignDatasetToGroup(String groupNameOrId, String datasetNameOrId) { return assignDatasetToGroupBody(groupNameOrId, datasetNameOrId, false); } - - /* (non-Javadoc) - * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue#patchProductCustomFields(java.lang.String, java.lang.String, java.util.Map, boolean) + + /* + * (non-Javadoc) + * + * @see org.gcube.datacatalogue.utillibrary.server.DataCatalogue# + * patchProductCustomFields(java.lang.String, java.lang.String, java.util.Map, + * boolean) */ - //TODO HAS TO BE REVISITED by gCAT + /** + * Patch product custom fields. + * + * @param productId the product id + * @param username the username + * @param customFieldsToChange the custom fields to change + * @param removeOld the remove old + * @return true, if successful + */ + // TODO HAS TO BE REVISITED by gCAT @Override public boolean patchProductCustomFields(String productId, String username, Map> customFieldsToChange, boolean removeOld) { @@ -1265,34 +1697,33 @@ public class DataCatalogueImpl implements DataCatalogue { checkNotNull(productId); checkNotNull(username); - if(customFieldsToChange == null || customFieldsToChange.isEmpty()) // TODO.. remove all custom fields maybe?! + if (customFieldsToChange == null || customFieldsToChange.isEmpty()) // TODO.. remove all custom fields maybe?! return true; - + String apiKey = getApiKeyFromUsername(username); - LOG.info("Going to change product with id " + productId +"." - + " Request comes from user with key " + apiKey.substring(0, 5) + "****************"); + LOG.info("Going to change product with id " + productId + "." + " Request comes from user with key " + + apiKey.substring(0, 5) + "****************"); LOG.info("The new values are " + customFieldsToChange); // Get already available custom fields Map> fromCKANCustomFields = new HashMap>(); - ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, apiKey); List extras = client.getDataset(productId).getExtras(); - if(extras == null) + if (extras == null) extras = new ArrayList(); // fill the above map with these values for (CkanPair ckanPair : extras) { List forThisValue = null; String key = ckanPair.getKey(); - if(fromCKANCustomFields.containsKey(key)) + if (fromCKANCustomFields.containsKey(key)) forThisValue = fromCKANCustomFields.get(key); else - forThisValue = new ArrayList(); + forThisValue = new ArrayList(); forThisValue.add(ckanPair.getValue()); fromCKANCustomFields.put(key, forThisValue); } @@ -1302,8 +1733,7 @@ public class DataCatalogueImpl implements DataCatalogue { // merge them with the new values Iterator>> iteratorUserMap = customFieldsToChange.entrySet().iterator(); while (iteratorUserMap.hasNext()) { - Map.Entry> entry = iteratorUserMap - .next(); + Map.Entry> entry = iteratorUserMap.next(); String key = entry.getKey(); List newValues = entry.getValue(); @@ -1311,8 +1741,8 @@ public class DataCatalogueImpl implements DataCatalogue { // get the unique set of values Set uniqueValues = new HashSet(); - if(fromCKANCustomFields.containsKey(key)) - if(!removeOld) + if (fromCKANCustomFields.containsKey(key)) + if (!removeOld) uniqueValues.addAll(fromCKANCustomFields.get(key)); uniqueValues.addAll(newValues); @@ -1329,13 +1759,13 @@ public class DataCatalogueImpl implements DataCatalogue { // Request parameters to be replaced JSONObject jsonRequest = new JSONObject(); - // build the json array for the "extras" field.. each object looks like {"key": ..., "value": ...} + // build the json array for the "extras" field.. each object looks like {"key": + // ..., "value": ...} JSONArray extrasObject = new JSONArray(); Iterator>> iteratorNewFields = fromCKANCustomFields.entrySet().iterator(); while (iteratorNewFields.hasNext()) { - Map.Entry> entry = iteratorNewFields - .next(); + Map.Entry> entry = iteratorNewFields.next(); String key = entry.getKey(); List values = entry.getValue(); @@ -1360,26 +1790,25 @@ public class DataCatalogueImpl implements DataCatalogue { HttpResponse response = httpClient.execute(httpPostRequest); if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) { - throw new RuntimeException("failed to patch the product. response status line from " - + apiRequestUrl + " was: " + response.getStatusLine()); + throw new RuntimeException("failed to patch the product. response status line from " + apiRequestUrl + + " was: " + response.getStatusLine()); } return true; - }catch(Exception e){ + } catch (Exception e) { LOG.error("Failed to patch the product ", e); } return false; } - /** * The real body of the assignDatasetToGroup. * - * @param groupNameOrId the group name or id + * @param groupNameOrId the group name or id * @param datasetNameOrId the dataset name or id - * @param addOnParents the add on parents + * @param addOnParents the add on parents * @return true, if successful */ private boolean assignDatasetToGroupBody(String groupNameOrId, String datasetNameOrId, boolean addOnParents) { @@ -1392,7 +1821,7 @@ public class DataCatalogueImpl implements DataCatalogue { String groupNameToCheck = CatalogueUtilMethods.fromGroupTitleToName(groupNameOrId); - try(CloseableHttpClient httpClient = HttpClientBuilder.create().build();){ + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { ExtendCkanClient client = new ExtendCkanClient(CKAN_CATALOGUE_URL, CKAN_TOKEN_SYS); @@ -1402,7 +1831,7 @@ public class DataCatalogueImpl implements DataCatalogue { // move to a list List groupNames = new ArrayList(); groupNames.add(group.getName()); - if(group != null && addOnParents){ + if (group != null && addOnParents) { findHierarchyGroups(groupNames, CKAN_TOKEN_SYS); } @@ -1412,25 +1841,27 @@ public class DataCatalogueImpl implements DataCatalogue { getRequest.addHeader("Authorization", CKAN_TOKEN_SYS); HttpResponse response = httpClient.execute(getRequest); - LOG.debug("Response is " + response.getStatusLine().getStatusCode() + " and message is " + response.getStatusLine().getReasonPhrase()); + LOG.debug("Response is " + response.getStatusLine().getStatusCode() + " and message is " + + response.getStatusLine().getReasonPhrase()); - // read the json dataset and fetch the groups and fetch the groups' names, if any - if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ + // read the json dataset and fetch the groups and fetch the groups' names, if + // any + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // parse the json and convert to java beans String jsonAsString = EntityUtils.toString(response.getEntity()); JSONParser parser = new JSONParser(); JSONObject json = (JSONObject) parser.parse(jsonAsString); - JSONObject resultJson = (JSONObject) json.get("result"); - JSONArray groupsJson = (JSONArray)resultJson.get("groups"); - Iterator it = groupsJson.iterator(); + JSONObject resultJson = (JSONObject) json.get("result"); + JSONArray groupsJson = (JSONArray) resultJson.get("groups"); + Iterator it = groupsJson.iterator(); while (it.hasNext()) { JSONObject object = it.next(); - try{ - if(object.containsKey("name")) - groupNames.add((String)object.get("name")); - }catch(Exception e){ + try { + if (object.containsKey("name")) + groupNames.add((String) object.get("name")); + } catch (Exception e) { LOG.error("Error", e); } } @@ -1463,38 +1894,37 @@ public class DataCatalogueImpl implements DataCatalogue { StringEntity params = new StringEntity(req.toJSONString()); request.setEntity(params); HttpResponse responsePatch = httpClient.execute(request); - LOG.debug("Response code is " + responsePatch.getStatusLine().getStatusCode() + " and response message is " + responsePatch.getStatusLine().getReasonPhrase()); + LOG.debug("Response code is " + responsePatch.getStatusLine().getStatusCode() + + " and response message is " + responsePatch.getStatusLine().getReasonPhrase()); - if(responsePatch.getStatusLine().getStatusCode() == HttpStatus.SC_OK){ + if (responsePatch.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { LOG.info("Dataset Added to the group!!"); return true; } } - }catch(Exception e){ + } catch (Exception e) { LOG.error("Unable to make this association", e); } return false; } - + /** * Find the hierarchy of trees. * * @param groupsTitles the groups titles - * @param apiKey the api key + * @param apiKey the api key */ - private void findHierarchyGroups( - List groupsTitles, - String apiKey) { + private void findHierarchyGroups(List groupsTitles, String apiKey) { ListIterator iterator = groupsTitles.listIterator(); while (iterator.hasNext()) { String group = iterator.next(); List parents = getParentGroups(group, apiKey); - if(parents == null || parents.isEmpty()) + if (parents == null || parents.isEmpty()) return; for (CkanGroup ckanGroup : parents) { @@ -1507,8 +1937,7 @@ public class DataCatalogueImpl implements DataCatalogue { } } - - + /** * ***************************************************************************** * @@ -1518,42 +1947,42 @@ public class DataCatalogueImpl implements DataCatalogue { * * *****************************************************************************. * - * @param username the username + * @param username the username * @param sourceOrganization the source organization - * @param currentRole the current role + * @param currentRole the current role */ - + @Override - public void assignRolesOtherOrganization(String username, - String sourceOrganization, RolesCkanGroupOrOrg currentRole) { + public void assignRolesOtherOrganization(String username, String sourceOrganization, + RolesCkanGroupOrOrg currentRole) { checkNotNull(username); checkNotNull(sourceOrganization); checkNotNull(currentRole); - LOG.info("Request for assigning other roles for user " + username + ", whose current role is " + currentRole + " and organization " + sourceOrganization); + LOG.info("Request for assigning other roles for user " + username + ", whose current role is " + currentRole + + " and organization " + sourceOrganization); Iterator> iterator = extendRoleInOrganization.entrySet().iterator(); LOG.debug("List of entries to check is " + extendRoleInOrganization); while (iterator.hasNext()) { - Map.Entry entry = iterator - .next(); + Map.Entry entry = iterator.next(); String sourceOrg = entry.getKey(); LOG.debug("Found organization source " + sourceOrg); - if(sourceOrg.equals(sourceOrganization)){ + if (sourceOrg.equals(sourceOrganization)) { String[] values = entry.getValue().split(DataCatalogueRunningCluster.TUPLES_SEPARATOR); - for(int i = 0; i < values.length; i++){ + for (int i = 0; i < values.length; i++) { - String destOrg = values[i].split("\\"+DataCatalogueRunningCluster.ROLE_ORGANIZATION_SEPARATOR)[0]; - String role = values[i].split("\\"+DataCatalogueRunningCluster.ROLE_ORGANIZATION_SEPARATOR)[1]; + String destOrg = values[i].split("\\" + DataCatalogueRunningCluster.ROLE_ORGANIZATION_SEPARATOR)[0]; + String role = values[i].split("\\" + DataCatalogueRunningCluster.ROLE_ORGANIZATION_SEPARATOR)[1]; LOG.debug("Role is " + role + " and organization is " + destOrg); RolesCkanGroupOrOrg ckanRole; - if(role.equals(DataCatalogueRunningCluster.CKAN_GENERIC_ROLE)) + if (role.equals(DataCatalogueRunningCluster.CKAN_GENERIC_ROLE)) ckanRole = currentRole; else ckanRole = RolesCkanGroupOrOrg.convertFromCapacity(role); diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/server/cms/CatalogueContentModeratorSystem.java b/src/main/java/org/gcube/datacatalogue/utillibrary/server/cms/CatalogueContentModeratorSystem.java new file mode 100644 index 0000000..8d00881 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/server/cms/CatalogueContentModeratorSystem.java @@ -0,0 +1,88 @@ +package org.gcube.datacatalogue.utillibrary.server.cms; + +import java.io.InvalidObjectException; +import java.net.MalformedURLException; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.WebApplicationException; +import javax.xml.ws.WebServiceException; + +import org.gcube.datacatalogue.utillibrary.shared.ItemStatus; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanDataset; + +/** + * The Interface CatalogueContentModeratorSystem. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jan 10, 2022 + */ +public interface CatalogueContentModeratorSystem { + + /** + * Checks if is moderation enabled. + * + * @param reloadConfig the reload config + * @return true, if is moderation enabled + * @throws MalformedURLException + */ + boolean isModerationEnabled(boolean reloadConfig) throws MalformedURLException; + + /** + * Gets the list items for status. + * + * @param theStatus the the status + * @param limit the limit + * @param offset the offset + * @param filters add the input filters to query on CKAN + * @param sortForField the sort for field + * @return the list items for status + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + * @throws InvalidObjectException the invalid object exception + */ + public List getListItemsForStatus(ItemStatus theStatus, int limit, int offset, + Map filters, String sortForField) throws WebApplicationException, MalformedURLException, InvalidObjectException; + + /** + * Reject item. + * + * @param itemName the item name + * @param permanentlyDelete the permanently delete + * @param reasonMsg the reason msg + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + void rejectItem(String itemName, boolean permanentlyDelete, String reasonMsg) + throws WebServiceException, MalformedURLException; + + /** + * Permanently delete. + * + * @param itemName the item name + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + void permanentlyDelete(String itemName) throws WebServiceException, MalformedURLException; + + /** + * Count list items for status. + * + * @param theStatus the the status + * @param filters add the input filters to query on CKAN + * @return the long + */ + long countListItemsForStatus(ItemStatus theStatus, Map filters); + + /** + * Approve item. + * + * @param itemName the item name + * @param moderatorMessage the moderator message + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + void approveItem(String itemName, String moderatorMessage) throws WebApplicationException, MalformedURLException; + +} diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/server/cms/DataCatalogueCMSImpl.java b/src/main/java/org/gcube/datacatalogue/utillibrary/server/cms/DataCatalogueCMSImpl.java new file mode 100644 index 0000000..c5ba458 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/server/cms/DataCatalogueCMSImpl.java @@ -0,0 +1,252 @@ +package org.gcube.datacatalogue.utillibrary.server.cms; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; +import java.io.InvalidObjectException; +import java.net.MalformedURLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.WebApplicationException; +import javax.xml.ws.WebServiceException; + +import org.gcube.datacatalogue.utillibrary.ckan.MarshUnmarshCkanObject; +import org.gcube.datacatalogue.utillibrary.ckan.MarshUnmarshCkanObject.METHOD; +import org.gcube.datacatalogue.utillibrary.gcat.GCatCaller; +import org.gcube.datacatalogue.utillibrary.shared.ItemStatus; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanDataset; +import org.gcube.gcat.api.moderation.CMItemStatus; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Class DataCatalogueCMSImpl. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Jun 14, 2021 + */ +public class DataCatalogueCMSImpl implements CatalogueContentModeratorSystem { + + private static final Logger LOG = LoggerFactory.getLogger(DataCatalogueCMSImpl.class); + private String runningScope; + private GCatCaller gCatCaller; + + /** + * Instantiates a new data catalogue CMS impl. + * + * @param runningScope the running scope + * @param gCatCaller the g cat caller + */ + public DataCatalogueCMSImpl(String runningScope, GCatCaller gCatCaller) { + this.runningScope = runningScope; + this.gCatCaller = gCatCaller; + } + + /** + * Checks if is Moderation is enabled in the working scope + * + * @return true, if is content moderator enabled + * @throws MalformedURLException + */ + @Override + public boolean isModerationEnabled(boolean reloadConfig) throws MalformedURLException { + return gCatCaller.getConfiguration(reloadConfig).isModerationEnabled(); + } + + /** + * Approve item. + * + * @param datasetName the dataset name + * @param moderatorMessage the moderator message + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + */ + @Override + public void approveItem(String datasetName, String moderatorMessage) + throws WebApplicationException, MalformedURLException { + gCatCaller.approveItem(datasetName, moderatorMessage); + + } + + /** + * Reject item. + * + * @param datasetName the dataset name + * @param permanentlyDelete the permanently delete + * @param moderatorMessage the moderator message + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + @Override + public void rejectItem(String datasetName, boolean permanentlyDelete, String moderatorMessage) + throws WebServiceException, MalformedURLException { + gCatCaller.rejectItem(datasetName, permanentlyDelete, moderatorMessage); + + } + + /** + * Permanently delete. + * + * @param datasetName the dataset name + * @throws WebServiceException the web service exception + * @throws MalformedURLException the malformed URL exception + */ + @Override + public void permanentlyDelete(String datasetName) throws WebServiceException, MalformedURLException { + gCatCaller.deleteItem(datasetName, true); + + } + + /** + * Gets the running scope. + * + * @return the running scope + */ + public String getRunningScope() { + return runningScope; + } + + /** + * Gets the list items for status. + * + * @param theStatus the the status + * @param limit the limit + * @param offset the offset + * @param filters add the input filters to query on CKAN + * @param sortForField the sort for field + * @return the list items for status + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + * @throws InvalidObjectException the invalid object exception + */ + @Override + public List getListItemsForStatus(ItemStatus theStatus, int limit, int offset, + Map filters, String sortForField) throws WebApplicationException, MalformedURLException, InvalidObjectException { + LOG.info("called getListItemsForStatus with [status: " + theStatus + "], [limit: " + limit + "], [offset: " + + offset + "], [filters: " + filters + "]"); + List listDataset = null; + checkNotNull(theStatus); + JSONArray jsonArray = getSourceArrayOfItemsForStatus(theStatus, limit, offset, filters, sortForField); + + if (jsonArray != null) { + int size = jsonArray.size(); + listDataset = new ArrayList(size); + LOG.info("reading and converting " + size + " dataset..."); + for (int i = 0; i < size; i++) { + String datasetName = null; + try { + datasetName = (String) jsonArray.get(i); + LOG.debug("reading dataset: " + datasetName); + String jsonValueDataset = gCatCaller.getDatasetForName(datasetName); + LOG.trace("the JSON dataset is: " + jsonValueDataset); + CkanDataset toCkanDataset = MarshUnmarshCkanObject.toCkanDataset(jsonValueDataset, METHOD.TO_READ); + LOG.debug("converted as dataset: " + toCkanDataset); + listDataset.add(toCkanDataset); + } catch (IOException e) { + LOG.warn("Error on reading/converting the dataset name: " + datasetName, e); + } + } + } + + if (listDataset == null) { + LOG.info("no dataset returned with status: " + theStatus); + return listDataset; + } + + LOG.info("returning listDataset with size: " + listDataset.size()); + return listDataset; + } + + /** + * Count list items for status. + * + * @param theStatus the the status + * @param filters add the input filters to query on CKAN + * @return the number of items with the input status + */ + @Override + public long countListItemsForStatus(ItemStatus theStatus, Map filters) { + LOG.info("called countListItemsForStatus with [status: " + theStatus + "]"); + checkNotNull(theStatus); + int count = 0; + try { + CMItemStatus cmStatus = toCMStatus(theStatus); + count = gCatCaller.countListItemsForCMStatus(cmStatus, filters); + } catch (Exception e) { + LOG.error("Error on counting the items for status " + theStatus, e); + return -1; + } + + return count; + + } + + /** + * Gets the source array of items for status read by gCatClient. + * + * @param theStatus the the status + * @param limit the limit + * @param offset the offset + * @param filters the filters + * @param sortForField the sort for field + * @return the source array of items for status + * @throws WebApplicationException the web application exception + * @throws MalformedURLException the malformed URL exception + * @throws InvalidObjectException the invalid object exception + */ + protected org.json.simple.JSONArray getSourceArrayOfItemsForStatus(ItemStatus theStatus, int limit, int offset, + Map filters, String sortForField) throws WebApplicationException, MalformedURLException, InvalidObjectException { + LOG.info("called getSourceArrayOfItemsForStatus with [status: " + theStatus + "], [limit: " + limit + + "], [offset: " + offset + "], [filters: " + filters + "]"); + checkNotNull(theStatus); + // TODO MUST BE CHANGED FOR THE STATUS + org.json.simple.JSONArray jsonArray = null; + + /* + * String datasetNames = null; if(theStatus.equals(ItemStatus.PUBLISHED)) { + * datasetNames = gCatCaller.getListItems(limit, offset); }else { CMItemStatus + * cmiStatus = toCMStatus(theStatus); datasetNames = + * gCatCaller.getListItemsForCMStatus(cmiStatus, limit, offset); } + */ + + CMItemStatus cmiStatus = toCMStatus(theStatus); + String datasetNames = gCatCaller.getListItemsForCMStatus(cmiStatus, limit, offset, filters, sortForField); + + if (datasetNames != null) { + LOG.debug("for status " + theStatus + " found dataset: " + datasetNames); + JSONParser parser = new JSONParser(); + try { + jsonArray = (JSONArray) parser.parse(datasetNames); + } catch (ParseException e) { + LOG.error("error occurred reading " + datasetNames + " as JSONArray", e); + throw new InvalidObjectException(e.getMessage()); + } + } + + return jsonArray; + + } + + /** + * To CM status. + * + * @param theStatus the the status + * @return the CM item status + * @throws WebApplicationException the web application exception + */ + private CMItemStatus toCMStatus(ItemStatus theStatus) throws WebApplicationException { + try { + return CMItemStatus.valueOf(theStatus.name()); + } catch (Exception e) { + throw new WebApplicationException( + "No value of " + theStatus.name() + " into enumerator: " + CMItemStatus.values()); + } + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/server/utils/GCubeUtils.java b/src/main/java/org/gcube/datacatalogue/utillibrary/server/utils/GCubeUtils.java index 6fc4535..78906e6 100644 --- a/src/main/java/org/gcube/datacatalogue/utillibrary/server/utils/GCubeUtils.java +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/server/utils/GCubeUtils.java @@ -96,15 +96,16 @@ public class GCubeUtils { /** - * Detect the OrgName contexts (token and scope) if the working context (in the thread) is a root VO or VO and switch to it according to setInThread parameters + * Detect the organizationName context (token and scope of VRE). + * If the working context (in the thread) is a root VO or VO and setInThread is true then switch to VRE context (setting ScopeProvider and SecurityTokenProvider) * * @param organizationName the organization name to switch to * @param username the username - * @param setInThread set in the target token (in the {@link SecurityTokenProvider}) and the scope (in the {@link ScopeProvider}) detected for the OrgName - * @return the gcube context + * @param setInThread if true set the target token (in the {@link SecurityTokenProvider}) and the scope (in the {@link ScopeProvider}) detected for the OrgName + * @return the gcube context with source scope/token and target (detected for organizationName) scope/token * @throws Exception the exception */ - public static GcubeContext detectTheOrgNameContexts(String organizationName, String username, boolean setInThread) throws Exception { + public static GcubeContext detectAndSetTheOrgNameContext(String organizationName, String username, boolean setInThread) throws Exception { String scope = ScopeProvider.instance.get(); String token = SecurityTokenProvider.instance.get(); diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/shared/GCatCatalogueConfiguration.java b/src/main/java/org/gcube/datacatalogue/utillibrary/shared/GCatCatalogueConfiguration.java new file mode 100644 index 0000000..66c5409 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/shared/GCatCatalogueConfiguration.java @@ -0,0 +1,113 @@ +package org.gcube.datacatalogue.utillibrary.shared; + +import java.io.Serializable; +import java.util.Set; + +public class GCatCatalogueConfiguration implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -1250433017161647236L; + private String context; + private String defaultOrganization; + private Set supportedOrganizations; + + private String ckanURL; + private String solrURL; + private boolean socialPostEnabled; + private boolean notificationToUsersEnabled; + private boolean moderationEnabled; + + public GCatCatalogueConfiguration() { + + } + + public String getContext() { + return context; + } + + public String getDefaultOrganization() { + return defaultOrganization; + } + + public Set getSupportedOrganizations() { + return supportedOrganizations; + } + + public String getCkanURL() { + return ckanURL; + } + + public String getSolrURL() { + return solrURL; + } + + public boolean isSocialPostEnabled() { + return socialPostEnabled; + } + + public boolean isNotificationToUsersEnabled() { + return notificationToUsersEnabled; + } + + public boolean isModerationEnabled() { + return moderationEnabled; + } + + public void setContext(String context) { + this.context = context; + } + + public void setDefaultOrganization(String defaultOrganization) { + this.defaultOrganization = defaultOrganization; + } + + public void setSupportedOrganizations(Set supportedOrganizations) { + this.supportedOrganizations = supportedOrganizations; + } + + public void setCkanURL(String ckanURL) { + this.ckanURL = ckanURL; + } + + public void setSolrURL(String solrURL) { + this.solrURL = solrURL; + } + + public void setSocialPostEnabled(boolean socialPostEnabled) { + this.socialPostEnabled = socialPostEnabled; + } + + public void setNotificationToUsersEnabled(boolean notificationToUsersEnabled) { + this.notificationToUsersEnabled = notificationToUsersEnabled; + } + + public void setModerationEnabled(boolean moderationEnabled) { + this.moderationEnabled = moderationEnabled; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("GCatCatalogueConfiguration [context="); + builder.append(context); + builder.append(", defaultOrganization="); + builder.append(defaultOrganization); + builder.append(", supportedOrganizations="); + builder.append(supportedOrganizations); + builder.append(", ckanURL="); + builder.append(ckanURL); + builder.append(", solrURL="); + builder.append(solrURL); + builder.append(", socialPostEnabled="); + builder.append(socialPostEnabled); + builder.append(", notificationToUsersEnabled="); + builder.append(notificationToUsersEnabled); + builder.append(", moderationEnabled="); + builder.append(moderationEnabled); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/src/main/java/org/gcube/datacatalogue/utillibrary/shared/ItemStatus.java b/src/main/java/org/gcube/datacatalogue/utillibrary/shared/ItemStatus.java new file mode 100644 index 0000000..9ee3456 --- /dev/null +++ b/src/main/java/org/gcube/datacatalogue/utillibrary/shared/ItemStatus.java @@ -0,0 +1,48 @@ +package org.gcube.datacatalogue.utillibrary.shared; + +/** + * The Enum ItemStatus. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Feb 17, 2022 + */ +public enum ItemStatus { + PENDING("pending", "Pending"), APPROVED("approved", "Approved"), REJECTED("rejected", "Rejected"); + // Published means that the item is published in the Catalogue, no status is checked, + // the "simple" get list of items is called + //PUBLISHED("published", "Published"); + + private String id; + private String label; + + /** + * Instantiates a new item status. + * + * @param id the id + * @param label the label + */ + private ItemStatus(String id, String label) { + this.id = id; + this.label = label; + } + + /** + * Gets the id. + * + * @return the id + */ + public String getId() { + return id; + } + + /** + * Gets the label. + * + * @return the label + */ + public String getLabel() { + return label; + } + +} \ No newline at end of file diff --git a/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueCMS.java b/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueCMS.java new file mode 100644 index 0000000..cf78fbf --- /dev/null +++ b/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueCMS.java @@ -0,0 +1,160 @@ +package org.gcube.datacatalogue.utillibrary.test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.datacatalogue.utillibrary.gcat.GCatCaller; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueFactory; +import org.gcube.datacatalogue.utillibrary.server.DataCatalogueImpl; +import org.gcube.datacatalogue.utillibrary.server.cms.CatalogueContentModeratorSystem; +import org.gcube.datacatalogue.utillibrary.shared.ItemStatus; +import org.gcube.datacatalogue.utillibrary.shared.jackan.model.CkanDataset; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.LoggerFactory; + +/** + * The Class TestDataCatalogueLib. + * + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) Jun 1, 2020 + */ +public class TestDataCatalogueCMS { + + private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(TestDataCatalogueCMS.class); + + private DataCatalogueFactory factory; + private String scope = "/gcube/devsec/devVRE"; + private String testUser = "francesco.mangiacrapa"; + private String authorizationToken = ""; + + /** + * Before. + * + * @throws Exception the exception + */ + @Before + public void before() throws Exception { + factory = DataCatalogueFactory.getFactory(); + } + + /** + * Factory test. + * + * @throws Exception the exception + */ + // @Test + public void contentModeratorTest() throws Exception { + ScopeProvider.instance.set(scope); + SecurityTokenProvider.instance.set(authorizationToken); + DataCatalogueFactory factory = DataCatalogueFactory.getFactory(); + DataCatalogueImpl dImpl = factory.getUtilsPerScope(scope); + CatalogueContentModeratorSystem cCMS = dImpl.getCatalogueContentModerator(); + LOG.debug(CatalogueContentModeratorSystem.class.getName() + " instancied correclty"); + } + + // @Test + public void listItemsForCMStatus() throws Exception { + ItemStatus theStatus = ItemStatus.PENDING; + ScopeProvider.instance.set(scope); + SecurityTokenProvider.instance.set(authorizationToken); + DataCatalogueImpl dImpl = factory.getUtilsPerScope(scope); + CatalogueContentModeratorSystem cCMS = dImpl.getCatalogueContentModerator(); + LOG.debug(CatalogueContentModeratorSystem.class.getName() + " instancied correclty"); + + List emailsAddresses = new ArrayList(); + // emailsAddresses.add("luca.frosini@isti.cnr.it"); + emailsAddresses.add("francesco.mangiacrapa@isti.cnr.it"); + // emailsAddresses.add("pagano@cnr.it"); + + String theQuery = mockQueryForEmails(emailsAddresses, "OR"); + + Map filters = new HashMap(); + filters.put("author_email", theQuery); + + List listItems = cCMS.getListItemsForStatus(theStatus, 10, 0, filters, GCatCaller.DEFAULT_SORT_VALUE); + int i = 0; + for (CkanDataset ckanDataset : listItems) { + System.out.println(++i + ") item returned: " + ckanDataset); + } + + } + + /** + * Gets the scope per url. + * + * @return the scope per url + * @throws Exception + */ + @Test + public void countListItemsForStatus() throws Exception { + + try { + ItemStatus theStatus = ItemStatus.APPROVED; + ScopeProvider.instance.set(scope); + SecurityTokenProvider.instance.set(authorizationToken); + DataCatalogueImpl dImpl = factory.getUtilsPerScope(scope); + CatalogueContentModeratorSystem cCMS = dImpl.getCatalogueContentModerator(); + LOG.debug(CatalogueContentModeratorSystem.class.getName() + " instancied correclty"); + + List emailsAddresses = new ArrayList(); + //emailsAddresses.add("luca.frosini@isti.cnr.it"); + //emailsAddresses.add("francesco.mangiacrapa@isti.cnr.it"); + //emailsAddresses.add("pagano@cnr.it"); + + String theQuery = mockQueryForEmails(emailsAddresses, "OR"); + + Map filters = new HashMap(); + filters.put("author_email", theQuery); + + long size = cCMS.countListItemsForStatus(theStatus, filters); + LOG.debug("Size of list of items for status " + theStatus + " is: " + size); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String mockQueryForEmails(List emailsAddresses, String queryOperator) throws Exception { + + StringBuilder queryMails = new StringBuilder(); + if (queryOperator == null) + queryOperator = "OR"; + // BUILDING EMAILS QUERY + int numberOfEmails = emailsAddresses.size(); + + String theQuery = ""; + + // case 1 email address + if (numberOfEmails == 1) { + theQuery = "'" + emailsAddresses.get(0) + "'"; + } else { + // case N > 1 email addresses + for (int i = 0; i < emailsAddresses.size() - 1; i++) { + String email = emailsAddresses.get(i); + if (i == 0) { + // opening the query and adding first email address + queryMails.append("('" + email + "'"); + } else { + // adding the operator and the email address + queryMails.append(" " + queryOperator + " '" + email + "'"); + } + } + + theQuery = queryMails.toString(); + + // to be sure that endsWith Operator + if (!theQuery.endsWith(queryOperator)) { + theQuery += " " + queryOperator + " "; + } + + // adding last email address and closing the query + theQuery += "'" + emailsAddresses.get(numberOfEmails - 1) + "')"; + } + + return theQuery; + } + +} \ No newline at end of file diff --git a/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueLib.java b/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueLib.java index ef22471..d452104 100644 --- a/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueLib.java +++ b/src/test/java/org/gcube/datacatalogue/utillibrary/test/TestDataCatalogueLib.java @@ -1,6 +1,5 @@ package org.gcube.datacatalogue.utillibrary.test; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -12,6 +11,7 @@ import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.datacatalogue.utillibrary.ckan.MarshUnmarshCkanObject; import org.gcube.datacatalogue.utillibrary.ckan.MarshUnmarshCkanObject.METHOD; +import org.gcube.datacatalogue.utillibrary.gcat.GCatCaller; import org.gcube.datacatalogue.utillibrary.server.ApplicationProfileScopePerUrlReader; import org.gcube.datacatalogue.utillibrary.server.DataCatalogueFactory; import org.gcube.datacatalogue.utillibrary.server.DataCatalogueImpl; @@ -24,13 +24,10 @@ import org.junit.Before; import org.junit.Test; import org.slf4j.LoggerFactory; - - /** * The Class TestDataCatalogueLib. * - * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) - * Jun 1, 2020 + * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) Jun 1, 2020 */ public class TestDataCatalogueLib { @@ -38,11 +35,13 @@ public class TestDataCatalogueLib { private DataCatalogueFactory factory; private String scope = "/gcube/devsec/devVRE"; - //private String scope = "/gcube"; - //private String scope = "/pred4s/preprod/preVRE"; - //private String scope = "/d4science.research-infrastructures.eu/SoBigData/Catalogue-TerritoriAperti"; - //private String scope = "/d4science.research-infrastructures.eu/gCubeApps/BiodiversityLab"; - //private String testUser = "costantino_perciante"; + // private String scope = "/gcube"; + // private String scope = "/pred4s/preprod/preVRE"; + // private String scope = + // "/d4science.research-infrastructures.eu/SoBigData/Catalogue-TerritoriAperti"; + // private String scope = + // "/d4science.research-infrastructures.eu/gCubeApps/BiodiversityLab"; + // private String testUser = "costantino_perciante"; private String testUser = "francesco.mangiacrapa"; private String authorizationToken = ""; String subjectId = "aa_father4"; @@ -54,24 +53,24 @@ public class TestDataCatalogueLib { * * @throws Exception the exception */ - //@Before - public void before() throws Exception{ + // @Before + public void before() throws Exception { factory = DataCatalogueFactory.getFactory(); } - + /** * Factory test. * * @throws Exception the exception */ - //@Test - public void factoryTest() throws Exception{ + // @Test + public void factoryTest() throws Exception { DataCatalogueFactory factory = DataCatalogueFactory.getFactory(); - while(true){ + while (true) { factory.getUtilsPerScope(scope); - Thread.sleep(60* 1000 * 3); + Thread.sleep(60 * 1000 * 3); factory.getUtilsPerScope(scope); break; } @@ -82,14 +81,14 @@ public class TestDataCatalogueLib { } } - + /** * Gets the scope per url. * * @return the scope per url */ - //@Test - public void getScopePerUrl(){ + // @Test + public void getScopePerUrl() { ScopeProvider.instance.set(scope); String url = "https://dev2.d4science.org/group/devvre/ckan"; @@ -101,16 +100,15 @@ public class TestDataCatalogueLib { String scopeToUse2 = ApplicationProfileScopePerUrlReader.getScopePerUrl(url2); LOG.debug("Retrieved scope is " + scopeToUse2); } - - + /** * Gets the user role by group. * * @return the user role by group * @throws Exception the exception */ - //@Test - public void getUserRoleByGroup() throws Exception{ + // @Test + public void getUserRoleByGroup() throws Exception { DataCatalogueImpl instance = factory.getUtilsPerScope(scope); String username = testUser; long init = System.currentTimeMillis(); @@ -118,30 +116,29 @@ public class TestDataCatalogueLib { long end = System.currentTimeMillis(); LOG.debug("Time taken " + (end - init)); } - + /** * Gets the user role by group. * * @return the user role by group * @throws Exception the exception */ - //@Test - public void getDataset() throws Exception{ + // @Test + public void getDataset() throws Exception { DataCatalogueImpl instance = factory.getUtilsPerScope(scope); String username = testUser; CkanDataset dataset = instance.getDataset("my_first_restful_transaction_model_private", username); - LOG.debug("Got dataset: " +dataset.getName() + ", with id: "+dataset.getId()); + LOG.debug("Got dataset: " + dataset.getName() + ", with id: " + dataset.getId()); } - /** * Gets the user role by organization. * * @return the user role by organization * @throws Exception the exception */ - //@Test - public void getUserRoleByOrganization() throws Exception{ + // @Test + public void getUserRoleByOrganization() throws Exception { DataCatalogueImpl instance = factory.getUtilsPerScope(scope); String username = testUser; long init = System.currentTimeMillis(); @@ -149,169 +146,155 @@ public class TestDataCatalogueLib { long end = System.currentTimeMillis(); LOG.debug("Time taken " + (end - init)); } - - //@Test - public void getRoleOfUserInOrganization() throws Exception{ - + + // @Test + public void getRoleOfUserInOrganization() throws Exception { + String orgName = "devvre"; DataCatalogueImpl utils = factory.getUtilsPerScope(scope); CkanOrganization org = utils.getOrganizationByIdOrName(orgName); String role = utils.getRoleOfUserInOrganization(testUser, org.getName()); - LOG.debug("The user "+testUser+" in the org "+org.getName() + " has the role "+role); + LOG.debug("The user " + testUser + " in the org " + org.getName() + " has the role " + role); } - - //@Test - public void getOrganizationForName() throws Exception{ - + + // @Test + public void getOrganizationForName() throws Exception { + String orgName = "devvre"; - + DataCatalogueImpl utils = factory.getUtilsPerScope(scope); - + CkanOrganization org = utils.getOrganizationByIdOrName(orgName); - - LOG.debug("The "+CkanOrganization.class.getSimpleName()+" is: "+org.getName()); - LOG.debug("LandingPages of "+CkanOrganization.class.getSimpleName()+" for name " + utils.getLandingPages()); - if(org.getUsers()!=null) { + + LOG.debug("The " + CkanOrganization.class.getSimpleName() + " is: " + org.getName()); + LOG.debug("LandingPages of " + CkanOrganization.class.getSimpleName() + " for name " + utils.getLandingPages()); + if (org.getUsers() != null) { for (CkanUser user : org.getUsers()) { - LOG.debug("User: "+user.getName()); + LOG.debug("User: " + user.getName()); } } } - - //@Test - public void getOrganizationsNamesByUser() throws Exception{ - + + // @Test + public void getOrganizationsNamesByUser() throws Exception { + DataCatalogueImpl utils = factory.getUtilsPerScope(scope); - + List listOrgs = utils.getOrganizationsByUser(testUser); - - LOG.debug("User :"+testUser+" found in the Organization/s:"); - + + LOG.debug("User :" + testUser + " found in the Organization/s:"); + for (CkanOrganization ckanOrganization : listOrgs) { - LOG.debug("Org: "+ckanOrganization.getName()); + LOG.debug("Org: " + ckanOrganization.getName()); } - - } - - //@Test - public void getGroupsNamesByUser() throws Exception{ - - DataCatalogueImpl utils = factory.getUtilsPerScope(scope); - - List listGroups = utils.getGroupsByUser(testUser); - - LOG.debug("User :"+testUser+" found in the Group/s:"); - - for (CkanGroup ckanGroup : listGroups) { - LOG.debug("Group: "+ckanGroup.getName()); - } - + } - //@Test - public void getLandingPages() throws Exception{ + // @Test + public void getGroupsNamesByUser() throws Exception { + + DataCatalogueImpl utils = factory.getUtilsPerScope(scope); + + List listGroups = utils.getGroupsByUser(testUser); + + LOG.debug("User :" + testUser + " found in the Group/s:"); + + for (CkanGroup ckanGroup : listGroups) { + LOG.debug("Group: " + ckanGroup.getName()); + } + + } + + // @Test + public void getLandingPages() throws Exception { DataCatalogueImpl utils = factory.getUtilsPerScope(scope); LOG.debug("Landing pages " + utils.getLandingPages()); } - - //@Test - public void countDatasetForOganization() throws Exception{ - - DataCatalogueImpl utils = new DataCatalogueImpl(scope,true); + + // @Test + public void countDatasetForOganization() throws Exception { + + DataCatalogueImpl utils = new DataCatalogueImpl(scope, true); List listOrgIds = utils.getOrganizationsIds(); - + System.out.println("'ORGANIZATION NAME': 'NUMBER OF PACKAGE'"); - + for (String orgID : listOrgIds) { CkanOrganization org = utils.getOrganizationByIdOrName(orgID); int packageCount = org.getPackageCount(); - //logger.info("ORG: "+org.getName() + " has "+packageCount+ " package/s"); - System.out.println(org.getName()+": "+packageCount); + // logger.info("ORG: "+org.getName() + " has "+packageCount+ " package/s"); + System.out.println(org.getName() + ": " + packageCount); } - + } - - //@Test - public void createDataset() throws Exception{ + + // @Test + public void createDataset() throws Exception { try { - + ScopeProvider.instance.set(scope); SecurityTokenProvider.instance.set(authorizationToken); - + DataCatalogueImpl instance = factory.getUtilsPerScope(scope); String licenseId = instance.getLicenses().get(0).getId(); - + Map> customFieldsMultiple = new HashMap>(); - + for (int i = 0; i < 10; i++) { List values = new ArrayList(); for (int j = 0; j < new Random().nextInt(3); j++) { - values.add("value-random-"+ new Random().nextInt(10)); + values.add("value-random-" + new Random().nextInt(10)); } - customFieldsMultiple.put("key-random-"+new Random().nextInt(10), values); + customFieldsMultiple.put("key-random-" + new Random().nextInt(10), values); } - + customFieldsMultiple.put("empty-key", Arrays.asList("")); - + customFieldsMultiple.put("system:type", Arrays.asList("EmptyProfile")); - + boolean setSearchable = true; boolean setPublic = true; List resources = null; - + String orgName = scope.split("/")[3].toLowerCase(); - //System.out.println("Org name by VRE: "+orgName); - LOG.debug("Org name by VRE: "+orgName); - + // System.out.println("Org name by VRE: "+orgName); + LOG.debug("Org name by VRE: " + orgName); + int random = new Random().nextInt(); - String datasetTitle = "a dataset created by catalogue-util-library "+random; + String datasetTitle = "a dataset created by catalogue-util-library " + random; String datasetName = datasetTitle.replace(" ", ""); - String createdDataset = instance.createCkanDatasetMultipleCustomFields( - testUser, - "a dataset created by catalogue-util-library "+random, - datasetName, - orgName, - testUser, - null, - null, - null, - 1, - "the description", - licenseId, - Arrays.asList("tag 1","tag 2","tag 3"), - customFieldsMultiple, - resources, - setPublic, - setSearchable, - true); - - LOG.info("Created the dataset with id: " +createdDataset); - }catch (Exception e) { + String createdDataset = instance.createCkanDatasetMultipleCustomFields(testUser, + "a dataset created by catalogue-util-library " + random, datasetName, orgName, testUser, null, null, + null, 1, "the description", licenseId, Arrays.asList("tag 1", "tag 2", "tag 3"), + customFieldsMultiple, resources, setPublic, setSearchable, true); + + LOG.info("Created the dataset with id: " + createdDataset); + } catch (Exception e) { e.printStackTrace(); } } - - //@Test - public void createGroup() throws Exception{ - + + // @Test + public void createGroup() throws Exception { + ScopeProvider.instance.set(scope); SecurityTokenProvider.instance.set(authorizationToken); - + DataCatalogueImpl instance = factory.getUtilsPerScope(scope); int random = new Random().nextInt(); - String groupTitle = "a grop created by catalogue-util-library "+random; + String groupTitle = "a grop created by catalogue-util-library " + random; String groupName = groupTitle.replace(" ", ""); CkanGroup ckanGroup = instance.createGroup(groupName, groupTitle, "description"); - LOG.info("Created the group: "+ckanGroup); + LOG.info("Created the group: " + ckanGroup); } - - //@Test + + // @Test public void addResource() throws Exception { ScopeProvider.instance.set(scope); @@ -323,11 +306,11 @@ public class TestDataCatalogueLib { for (int i = 1; i < 3; i++) { ResourceBean resourceBean = new ResourceBean("https://data-dev.d4science.net/ie8Y", "resouce " + i, "description " + i, null, testUser, dataset.getId(), null); - instance.addResourceToDataset(resourceBean,testUser,dataset.getOrganization().getName()); + instance.addResourceToDataset(resourceBean, testUser, dataset.getOrganization().getName()); } } - - //@Test + + // @Test public void deleteResource() throws Exception { ScopeProvider.instance.set(scope); @@ -337,43 +320,46 @@ public class TestDataCatalogueLib { String resourceId = "ce7295cf-47db-4faf-901f-4fec2d3fae7a"; boolean deleted = instance.deleteResourceFromDataset(resourceId, testUser); - LOG.info("Deleted the resource? "+deleted); + LOG.info("Deleted the resource? " + deleted); } - - //@Test - public void patchFieldsForDataset() throws Exception{ - + + // @Test + public void patchFieldsForDataset() throws Exception { + ScopeProvider.instance.set(scope); SecurityTokenProvider.instance.set(authorizationToken); - + DataCatalogueImpl instance = factory.getUtilsPerScope(scope); Map customFieldsToChange = new HashMap(); customFieldsToChange.put("key-random-0", "patched"); instance.patchFieldsForDataset(productName, customFieldsToChange); } - - //@Test - public void getUrlProduct() throws Exception{ - + + // @Test + public void getUrlProduct() throws Exception { + ScopeProvider.instance.set(scope); SecurityTokenProvider.instance.set(authorizationToken); - + DataCatalogueImpl instance = factory.getUtilsPerScope(scope); String datasetName = productName; String url = instance.getUnencryptedUrlFromDatasetIdOrName(datasetName); LOG.debug("url is " + url); } - - //@Test - public void marshallingDataset() throws Exception{ + + // @Test + public void marshallingDataset() throws Exception { DataCatalogueImpl instance = factory.getUtilsPerScope(scope); String username = testUser; CkanDataset dataset = instance.getDataset("sarda-sarda", username); - LOG.debug("Got dataset: " +dataset.getName() + ", with id: "+dataset.getId() +" is private: "+dataset.isPriv()); - String jsonValueDataset = MarshUnmarshCkanObject.toJsonValueDataset(dataset,METHOD.TO_CREATE); + LOG.debug("Got dataset: " + dataset.getName() + ", with id: " + dataset.getId() + " is private: " + + dataset.isPriv()); + String jsonValueDataset = MarshUnmarshCkanObject.toJsonValueDataset(dataset, METHOD.TO_CREATE); System.out.println(jsonValueDataset); dataset = MarshUnmarshCkanObject.toCkanDataset(jsonValueDataset, METHOD.TO_READ); System.out.println(dataset); - + } + + }