diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java index ee0963f..090c968 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/custom_annotations/CkanResource.java @@ -12,7 +12,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface CkanResource { - - boolean inspect() default false; } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthAccountingFilter.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthAccountingFilter.java index 81249e4..709a666 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthAccountingFilter.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/filters/RequestsAuthAccountingFilter.java @@ -16,6 +16,7 @@ import javax.ws.rs.ext.Provider; import org.gcube.common.authorization.library.AuthorizationEntry; import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; @@ -81,6 +82,7 @@ public class RequestsAuthAccountingFilter implements ContainerRequestFilter{ logger.debug("Setting scope " + ae.getContext()); AuthorizationProvider.instance.set(new Caller(ae.getClientInfo(), ae.getQualifier())); ScopeProvider.instance.set(ae.getContext()); + SecurityTokenProvider.instance.set(tokenInHeader); logger.info("Authorization entry set in thread local"); return; }else @@ -92,6 +94,7 @@ public class RequestsAuthAccountingFilter implements ContainerRequestFilter{ logger.debug("Setting scope " + ae.getContext()); AuthorizationProvider.instance.set(new Caller(ae.getClientInfo(), ae.getQualifier())); ScopeProvider.instance.set(ae.getContext()); + SecurityTokenProvider.instance.set(tokenAsQueryParameter); logger.info("Authorization entry set in thread local"); return; }else @@ -132,7 +135,7 @@ public class RequestsAuthAccountingFilter implements ContainerRequestFilter{ boolean isJson(ContainerRequestContext request) { // define rules when to read body - return request.getMediaType().toString().contains("application/json"); + return request.getMediaType().toString().contains(MediaType.APPLICATION_JSON); } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java index 3c141aa..10e0989 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Common.java @@ -12,6 +12,7 @@ import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CkanResource; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CustomField; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Tag; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Type; @@ -22,7 +23,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; * Information that both Stock and Fishery must contain * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ -@JsonIgnoreProperties(value = {"author", "author_contact", "extras"}, ignoreUnknown = true) // ignore in serialization/deserialization +@JsonIgnoreProperties(value = {"author", "author_contact", "extras", "product_type"}, ignoreUnknown = true) // ignore in serialization/deserialization public class Common { @JsonProperty("description") @@ -49,22 +50,23 @@ public class Common { private String maintainerContact; @JsonProperty("catches_or_landings") - @Valid @CkanResource - private Resource catchesOrLandings; + @Valid + private Resource catchesOrLandings; @JsonProperty("database_sources") @NotNull(message="database_source cannot be null") @Size(min=1, message="database_source cannot be empty") + @CkanResource @Valid - private List databaseSources; + private List> databaseSources; @JsonProperty("source_of_information") @NotNull(message="source_of_information cannot be null") @Size(min=1, message="source_of_information cannot be empty") @CkanResource @Valid - private List sourceOfInformation; + private List> sourceOfInformation; @JsonProperty("data_owner") @CustomField(key="Data owner") @@ -78,19 +80,20 @@ public class Common { @JsonProperty("short_title") @CustomField(key="Short Title") - @NotNull + @NotNull(message="short_title cannot be null") @Size(min=1, message="short_title cannot be empty") private String shortTitle; @JsonProperty("uuid_knowledge_base") @CustomField(key="UUID Knowledge Base") - @NotNull + @NotNull(message="uuid_knowledge_base cannot be null") @Size(min=1, message="uuid_knowledge_base cannot be empty") + // This will be the identifier of the product!! private String uuid; @JsonProperty("traceability_flag") @CustomField(key="Traceability Flag") - @NotNull + @NotNull(message="traceability_flag cannot be null") private boolean traceabilityFlag; @JsonProperty("extras") @@ -103,6 +106,12 @@ public class Common { @NotNull(message="status cannot be null") private Status status; + // automatically compiled + @JsonProperty("product_type") + @CustomField(key="Product type") + @Tag + private String productType; + public Common() { super(); } @@ -124,14 +133,17 @@ public class Common { * @param uuid * @param traceabilityFlag * @param extras + * @param status + * @param productType */ public Common(String description, String license, String author, Long version, String authorContact, String maintainer, - String maintainerContact, Resource catchesOrLandings, - List databaseSources, - List sourceOfInformation, String dataOwner, Type type, - String shortTitle, String uuid, boolean traceabilityFlag, - Map> extras) { + String maintainerContact, Resource catchesOrLandings, + List> databaseSources, + List> sourceOfInformation, String dataOwner, + Type type, String shortTitle, String uuid, + boolean traceabilityFlag, Map> extras, + Status status, String productType) { super(); this.description = description; this.license = license; @@ -149,6 +161,16 @@ public class Common { this.uuid = uuid; this.traceabilityFlag = traceabilityFlag; this.extras = extras; + this.status = status; + this.productType = productType; + } + + public String getProductType() { + return productType; + } + + public void setProductType(String productType) { + this.productType = productType; } public String getDescription() { @@ -207,27 +229,27 @@ public class Common { this.maintainerContact = maintainerContact; } - public Resource getCatchesOrLandings() { + public Resource getCatchesOrLandings() { return catchesOrLandings; } - public void setCatchesOrLandings(Resource catchesOrLandings) { + public void setCatchesOrLandings(Resource catchesOrLandings) { this.catchesOrLandings = catchesOrLandings; } - public List getDatabaseSources() { + public List> getDatabaseSources() { return databaseSources; } - public void setDatabaseSources(List databaseSources) { + public void setDatabaseSources(List> databaseSources) { this.databaseSources = databaseSources; } - public List getSourceOfInformation() { + public List> getSourceOfInformation() { return sourceOfInformation; } - public void setSourceOfInformation(List sourceOfInformation) { + public void setSourceOfInformation(List> sourceOfInformation) { this.sourceOfInformation = sourceOfInformation; } @@ -299,6 +321,7 @@ public class Common { + ", dataOwner=" + dataOwner + ", type=" + type + ", shortTitle=" + shortTitle + ", uuid=" + uuid + ", traceabilityFlag=" + traceabilityFlag + ", extras=" - + extras + "]"; + + extras + ", status=" + status + ", productType=" + + productType + "]"; } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/DatabaseSource.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/DatabaseSource.java deleted file mode 100644 index 2376274..0000000 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/DatabaseSource.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.gcube.data_catalogue.grsf_publish_ws.json.input; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; -import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Tag; -import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * A resource object bean for the database source. The name description has a controlled vocabulary - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -@JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization -public class DatabaseSource { - - @JsonProperty("url") - @NotNull(message="'url' attribute of database_source cannot be null") - @Size(min=1, message="'url' attribute of database_source cannot be empty") - private String url; - - @JsonProperty("description") - private String description; - - @JsonProperty("name") - @Group - @Tag - @NotNull(message="'name' attribute of database_source is missing or wrong") - private Source name; - - public DatabaseSource() { - super(); - } - - public DatabaseSource(String url, String description, Source name) { - super(); - this.url = url; - this.description = description; - this.name = name; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Source getName() { - return name; - } - - public void setName(Source name) { - this.name = name; - } - - @Override - public String toString() { - return "DatabaseSource [url=" + url + ", description=" + description - + ", name=" + name + "]"; - } -} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java index 8523f1d..9554efd 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/Resource.java @@ -3,15 +3,17 @@ package org.gcube.data_catalogue.grsf_publish_ws.json.input; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; /** - * A resource object bean + * A resource object bean. The generic argument applies to the resource's name. * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ @JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization -public class Resource { +public class Resource { @JsonProperty("url") @NotNull(message="'url' field of a resource cannot be null") @@ -23,14 +25,13 @@ public class Resource { @JsonProperty("name") @NotNull(message="'name' field of a resource cannot be null") - @Size(min=1, message="'name' field of a resource cannot be empty") - private String name; + private T name; public Resource() { super(); } - public Resource(String url, String description, String name) { + public Resource(String url, String description, T name) { super(); this.url = url; this.description = description; @@ -53,18 +54,24 @@ public class Resource { this.description = description; } - public String getName() { + public T getName() { return name; } - public void setName(String name) { + public void setName(T name) { this.name = name; } @Override public String toString() { - return "Resource [url=" + url + ", description=" + description - + ", name=" + name + "]"; + // in case of @tag + Class nameClass = name.getClass(); + + if(nameClass.equals(Source.class)) + return name.toString(); + else + return "Resource [url=" + url + ", description=" + description + + ", name=" + name + "]"; } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java index 5f650cf..78d1d52 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/StockRecord.java @@ -6,10 +6,11 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CkanResource; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CustomField; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Tag; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Abundance_Level; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Exploitation_Rate; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -61,18 +62,24 @@ public class StockRecord extends Common{ private String stateOfMarineResource; @JsonProperty("exploitation_rate") - @Group + @CustomField(key="Exploitation Rate") @Tag - @CkanResource(inspect=true) @Valid - private Resource exploitationRate; + private List> exploitationRate; @JsonProperty("abundance_level") - @Group + @CustomField(key="Abundance Level") @Tag - @CkanResource(inspect=true) @Valid - private Resource abundanceLevel; + private List> abundanceLevel; + + @JsonProperty("exploitation_rate_for_grouping") + @Group + private Exploitation_Rate exploitationRateForGrouping; + + @JsonProperty("abundance_level_for_grouping") + @Group + private Abundance_Level abundanceLevelForGrouping; @JsonProperty("narrative_state_and_trend") @CustomField(key="Narrative state and trend") @@ -96,8 +103,7 @@ public class StockRecord extends Common{ @JsonProperty("water_area") @CustomField(key="Water Area") - private List waterArea;// TODO check that multiple values are mapped to ckan - + private List waterArea; public StockRecord() { super(); @@ -114,11 +120,12 @@ public class StockRecord extends Common{ * @param stateOfMarineResource * @param exploitationRate * @param abundanceLevel + * @param exploitationRateForGrouping + * @param abundanceLevelForGrouping * @param narrativeStateAndTrend * @param scientificAdvice * @param reportingEntity * @param reportingYear - * @param status * @param stockUri * @param waterArea */ @@ -126,10 +133,13 @@ public class StockRecord extends Common{ String speciesScientificName, String area, String exploitingFishery, String managementEntity, String assessmentMethods, String stateOfMarineResource, - Resource exploitationRate, Resource abundanceLevel, + List> exploitationRate, + List> abundanceLevel, + Exploitation_Rate exploitationRateForGrouping, + Abundance_Level abundanceLevelForGrouping, String narrativeStateAndTrend, String scientificAdvice, - String reportingEntity, Long reportingYear, - String stockUri, List waterArea) { + String reportingEntity, Long reportingYear, String stockUri, + List waterArea) { super(); this.stockName = stockName; this.stockID = stockID; @@ -141,6 +151,8 @@ public class StockRecord extends Common{ this.stateOfMarineResource = stateOfMarineResource; this.exploitationRate = exploitationRate; this.abundanceLevel = abundanceLevel; + this.exploitationRateForGrouping = exploitationRateForGrouping; + this.abundanceLevelForGrouping = abundanceLevelForGrouping; this.narrativeStateAndTrend = narrativeStateAndTrend; this.scientificAdvice = scientificAdvice; this.reportingEntity = reportingEntity; @@ -149,6 +161,24 @@ public class StockRecord extends Common{ this.waterArea = waterArea; } + public Exploitation_Rate getExploitationRateForGrouping() { + return exploitationRateForGrouping; + } + + public void setExploitationRateForGrouping( + Exploitation_Rate exploitationRateForGrouping) { + this.exploitationRateForGrouping = exploitationRateForGrouping; + } + + public Abundance_Level getAbundanceLevelForGrouping() { + return abundanceLevelForGrouping; + } + + public void setAbundanceLevelForGrouping( + Abundance_Level abundanceLevelForGrouping) { + this.abundanceLevelForGrouping = abundanceLevelForGrouping; + } + public String getStockUri() { return stockUri; } @@ -229,19 +259,19 @@ public class StockRecord extends Common{ this.stateOfMarineResource = stateOfMarineResource; } - public Resource getExploitationRate() { + public List> getExploitationRate() { return exploitationRate; } - public void setExploitationRate(Resource exploitationRate) { + public void setExploitationRate(List> exploitationRate) { this.exploitationRate = exploitationRate; } - public Resource getAbundanceLevel() { + public List> getAbundanceLevel() { return abundanceLevel; } - public void setAbundanceLevel(Resource abundanceLevel) { + public void setAbundanceLevel(List> abundanceLevel) { this.abundanceLevel = abundanceLevel; } @@ -287,10 +317,12 @@ public class StockRecord extends Common{ + ", stateOfMarineResource=" + stateOfMarineResource + ", exploitationRate=" + exploitationRate + ", abundanceLevel=" + abundanceLevel - + ", narrativeStateAndTrend=" + narrativeStateAndTrend - + ", scientificAdvice=" + scientificAdvice - + ", reportingEntity=" + reportingEntity + ", reportingYear=" - + reportingYear + ", stockUri=" + stockUri + ", waterArea=" - + waterArea + "]"; - } + + ", exploitationRateForGrouping=" + + exploitationRateForGrouping + ", abundanceLevelForGrouping=" + + abundanceLevelForGrouping + ", narrativeStateAndTrend=" + + narrativeStateAndTrend + ", scientificAdvice=" + + scientificAdvice + ", reportingEntity=" + reportingEntity + + ", reportingYear=" + reportingYear + ", stockUri=" + stockUri + + ", waterArea=" + waterArea + "]"; + } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/TimeSeriesBean.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/TimeSeriesBean.java new file mode 100644 index 0000000..c8f8301 --- /dev/null +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/input/TimeSeriesBean.java @@ -0,0 +1,70 @@ +package org.gcube.data_catalogue.grsf_publish_ws.json.input; + +import javax.validation.constraints.NotNull; + +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Abundance_Level; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Exploitation_Rate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + + + +/** + * A time series bean that contains couple + * @author Costantino Perciante at ISTI-CNR + * (costantino.perciante@isti.cnr.it) + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class TimeSeriesBean { + + @JsonProperty("value") + @NotNull(message="value of a time series cannot be null") + private T value; + + @JsonProperty("year") + @NotNull(message="year of a time series cannot be null") + private Long year; + + /** + * + */ + public TimeSeriesBean() { + super(); + } + /** + * @param value + * @param year + */ + public TimeSeriesBean(T value, Long year) { + super(); + this.value = value; + this.year = year; + } + public T getValue() { + return value; + } + public void setValue(T value) { + this.value = value; + } + public Long getYear() { + return year; + } + public void setYear(Long year) { + this.year = year; + } + + @Override + public String toString() { + + Class valueClass = value.getClass(); + + // when the value belongs to these classes annotated with @Tag.. + if(valueClass.equals(Abundance_Level.class) || valueClass.equals(Exploitation_Rate.class)) + return year + "-" + value; + + else + return "TimeSeriesBean [value=" + value + ", year=" + year + "]"; + } + +} diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java index 3e8e2a8..0c4cf44 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/json/output/ResponseCreationBean.java @@ -11,6 +11,9 @@ public class ResponseCreationBean { @JsonProperty("id") private String id; + + @JsonProperty("knowledge_base_id") + private String kbUuid; // the original uuid given by the KB @JsonProperty("product_url") String productUrl; @@ -24,12 +27,15 @@ public class ResponseCreationBean { /** * @param id + * @param kbUuid * @param productUrl * @param error */ - public ResponseCreationBean(String id, String productUrl, String error) { + public ResponseCreationBean(String id, String kbUuid, String productUrl, + String error) { super(); this.id = id; + this.kbUuid = kbUuid; this.productUrl = productUrl; this.error = error; } @@ -42,10 +48,6 @@ public class ResponseCreationBean { this.id = id; } - public String getProducttUrl() { - return productUrl; - } - public void setProductUrl(String productUrl) { this.productUrl = productUrl; } @@ -58,10 +60,21 @@ public class ResponseCreationBean { this.error = error; } - @Override - public String toString() { - return "ResponseCreationBean [id=" + id + ", productUrl=" + productUrl - + ", error=" + error + "]"; + public String getKbUuid() { + return kbUuid; } + public void setKbUuid(String kbUuid) { + this.kbUuid = kbUuid; + } + + public String getProductUrl() { + return productUrl; + } + + @Override + public String toString() { + return "ResponseCreationBean [id=" + id + ", kbUuid=" + kbUuid + + ", productUrl=" + productUrl + ", error=" + error + "]"; + } } diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java index 8e1cb16..650e94f 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherFisheryService.java @@ -1,7 +1,7 @@ package org.gcube.data_catalogue.grsf_publish_ws.services; +import java.net.URLEncoder; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,7 +33,6 @@ import org.gcube.data_catalogue.grsf_publish_ws.utils.HelperMethods; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; -import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; import org.slf4j.LoggerFactory; import eu.trentorise.opendata.jackan.model.CkanDataset; @@ -92,6 +91,7 @@ public class GrsfPublisherFisheryService { Caller caller = AuthorizationProvider.instance.get(); String username = caller.getClient().getId(); String context = ScopeProvider.instance.get(); + String token = SecurityTokenProvider.instance.get(); logger.info("Incoming request for creating a fishery record = " + record); logger.info("Request coming from user " + username + " in context " + context); @@ -133,11 +133,12 @@ public class GrsfPublisherFisheryService { } - // check the record has a name, at least + // The name of the product will be the uuid of the kb. The title will be the fishery's fishery_name. + String futureName = record.getUuid(); String futureTitle = record.getFisheryName(); String fishingArea = record.getFishingArea(); String jurisdictionArea = record.getJurisdictionArea(); - if(!HelperMethods.isValid(futureTitle)){ + if(!HelperMethods.isValid(futureName)){ status = Status.BAD_REQUEST; responseBean.setId(null); @@ -151,9 +152,7 @@ public class GrsfPublisherFisheryService { }else{ - logger.debug("Checking if such name [" + futureTitle + "]doesn't exist yet..."); - String futureName = UtilMethods.fromProductTitleToName(futureTitle); - logger.info("Transformed name is " + futureName); + logger.debug("Checking if such name [" + futureName + "] doesn't exist yet..."); boolean alreadyExist = catalogue.existProductWithNameOrId(futureName); if(alreadyExist){ @@ -164,11 +163,13 @@ public class GrsfPublisherFisheryService { throw new Exception("Sorry but a product with such name already exists!"); }else{ + + // set the type + record.setProductType(THIS_TYPE); // evaluate the tags of the product List tags = new ArrayList(); HelperMethods.getTags(tags, record); - tags.add(THIS_TYPE); // evaluate the groups List groups = new ArrayList(); @@ -183,12 +184,9 @@ public class GrsfPublisherFisheryService { // automatically retrieve the other ones HelperMethods.getExtras(customFields, record); - // add the type - customFields.put(HelperMethods.PRODUCT_TYPE, Arrays.asList(THIS_TYPE)); - // retrieve the user's email and fullname - String authorMail = HelperMethods.getUserEmail(context, SecurityTokenProvider.instance.get()); - String authorFullname = HelperMethods.getUserFullname(context, SecurityTokenProvider.instance.get()); + String authorMail = HelperMethods.getUserEmail(context, token); + String authorFullname = HelperMethods.getUserFullname(context, token); if(authorMail == null || authorFullname == null){ @@ -220,6 +218,7 @@ public class GrsfPublisherFisheryService { id = catalogue.createCKanDatasetMultipleCustomFields( catalogue.getApiKeyFromUsername(username), futureTitle, + futureName, organization, authorFullname, authorMail, @@ -239,7 +238,8 @@ public class GrsfPublisherFisheryService { responseBean.setId(id); status = Status.CREATED; responseBean.setError(null); - responseBean.setProductUrl(catalogue.getPortletUrl() + "?path=/dataset/" + futureName); + responseBean.setProductUrl(catalogue.getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + futureName, "UTF-8")); + responseBean.setKbUuid(record.getUuid()); if(!groups.isEmpty()){ logger.info("Launching thread for association to the list of groups " + groups); diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java index b011a30..39cc521 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/services/GrsfPublisherStockService.java @@ -1,7 +1,7 @@ package org.gcube.data_catalogue.grsf_publish_ws.services; +import java.net.URLEncoder; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,7 +33,6 @@ import org.gcube.data_catalogue.grsf_publish_ws.utils.HelperMethods; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; -import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; import org.slf4j.LoggerFactory; import eu.trentorise.opendata.jackan.model.CkanDataset; @@ -92,6 +91,7 @@ public class GrsfPublisherStockService { Caller caller = AuthorizationProvider.instance.get(); String username = caller.getClient().getId(); String context = ScopeProvider.instance.get(); + String token = SecurityTokenProvider.instance.get(); logger.info("Incoming request for creating a stock record = " + record); logger.info("Request coming from user " + username + " in context " + context); @@ -134,8 +134,9 @@ public class GrsfPublisherStockService { } // check the record has a name, at least + String futureName = record.getUuid(); String futureTitle = record.getStockName(); - if(!HelperMethods.isValid(futureTitle)){ + if(!HelperMethods.isValid(futureName)){ status = Status.BAD_REQUEST; responseBean.setId(null); @@ -143,9 +144,7 @@ public class GrsfPublisherStockService { }else{ - logger.debug("Checking if such name [" + futureTitle + "] doesn't exist yet..."); - String futureName = UtilMethods.fromProductTitleToName(futureTitle); - logger.info("Transformed name is " + futureName); + logger.debug("Checking if such name [" + futureName + "] doesn't exist yet..."); boolean alreadyExist = catalogue.existProductWithNameOrId(futureName); if(alreadyExist){ @@ -157,11 +156,13 @@ public class GrsfPublisherStockService { }else{ + // set the type + record.setProductType(THIS_TYPE); + // evaluate the tags of the product List tags = new ArrayList(); HelperMethods.getTags(tags, record); - tags.add(THIS_TYPE); - + // evaluate the groups List groups = new ArrayList(); HelperMethods.getGroups(groups, record); @@ -174,20 +175,17 @@ public class GrsfPublisherStockService { // automatically retrieve the other ones HelperMethods.getExtras(customFields, record); - - // add the type - customFields.put(HelperMethods.PRODUCT_TYPE, Arrays.asList(THIS_TYPE)); // retrieve the user's email and fullname - String authorMail = HelperMethods.getUserEmail(context, SecurityTokenProvider.instance.get()); - String authorFullname = HelperMethods.getUserFullname(context, SecurityTokenProvider.instance.get()); + String authorMail = HelperMethods.getUserEmail(context, token); + String authorFullname = HelperMethods.getUserFullname(context, token); if(authorMail == null || authorFullname == null){ logger.debug("Author fullname or mail missing, cannot continue"); responseBean.setId(null); status = Status.INTERNAL_SERVER_ERROR; - throw new Exception("Sorry but there was not possible to retrieve your fullname/email!"); + throw new Exception("Sorry but was not possible to retrieve your fullname/email!"); }else{ @@ -211,6 +209,7 @@ public class GrsfPublisherStockService { id = catalogue.createCKanDatasetMultipleCustomFields( catalogue.getApiKeyFromUsername(username), futureTitle, + futureName, organization, authorFullname, authorMail, @@ -230,7 +229,8 @@ public class GrsfPublisherStockService { responseBean.setId(id); status = Status.CREATED; responseBean.setError(null); - responseBean.setProductUrl(catalogue.getPortletUrl() + "?path=/dataset/" + futureName); + responseBean.setProductUrl(catalogue.getPortletUrl() + "?" + URLEncoder.encode("path=/dataset/" + futureName, "UTF-8")); + responseBean.setKbUuid(record.getUuid()); if(!groups.isEmpty()){ logger.info("Launching thread for association to the list of groups " + groups); diff --git a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java index 6d92516..75a3973 100644 --- a/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java +++ b/src/main/java/org/gcube/data_catalogue/grsf_publish_ws/utils/HelperMethods.java @@ -5,7 +5,6 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -18,9 +17,7 @@ import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CustomField; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Tag; import org.gcube.data_catalogue.grsf_publish_ws.json.input.Common; -import org.gcube.data_catalogue.grsf_publish_ws.json.input.DatabaseSource; import org.gcube.data_catalogue.grsf_publish_ws.json.input.Resource; -import org.gcube.data_catalogue.grsf_publish_ws.json.input.StockRecord; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status; import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; @@ -47,7 +44,6 @@ public abstract class HelperMethods { // to be retrieved from the web.xml private static final String PENDING_CONTEX_KEY = "PendingContext"; private static final String CONFIRMED_CONTEX_KEY = "ConfirmedContext"; - public static final String PRODUCT_TYPE = "Product type"; /** * Convert a group name to its id on ckan @@ -73,7 +69,7 @@ public abstract class HelperMethods { * @return * @throws Exception */ - public static DataCatalogue getDataCatalogueRunningInstance(String scope) throws Exception{ + public static DataCatalogue getDataCatalogueRunningInstance(String scope){ try{ DataCatalogueImpl instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scope); @@ -100,9 +96,22 @@ public abstract class HelperMethods { Object f = new PropertyDescriptor(field.getName(), current).getReadMethod().invoke(record); if(f != null){ + if(f instanceof List){ - tags.add(f.toString().trim()); + List asList = ((List) f); + logger.debug("The object annotated with @Tag is a list. Adding ... "); + for (Object object : asList) { + logger.debug(object.toString().trim()); + tags.add(object.toString().trim()); + } + }else{ + + logger.debug("The object annotated with @Tag is a simple one. Adding ... "); + logger.debug(f.toString().trim()); + tags.add(f.toString().trim()); + + } } }catch(Exception e){ logger.error("Failed ot read value for field " + field.getName() + " skipping", e); @@ -111,16 +120,8 @@ public abstract class HelperMethods { } } while((current = current.getSuperclass())!=null); - - // now parse also the Database Sources field - List sources = record.getDatabaseSources(); - for (DatabaseSource databaseSource : sources) { - logger.debug("Database source is " + databaseSource); - String nameAsTag = databaseSource.getName().toString(); - if(!tags.contains(nameAsTag)) - tags.add(nameAsTag); - - } + + logger.info("Tags are " + tags); } /** @@ -151,19 +152,7 @@ public abstract class HelperMethods { } while((current = current.getSuperclass())!=null); - logger.debug("Groups is " + groups); - - // now parse also the Database Sources field - List sources = record.getDatabaseSources(); - for (DatabaseSource databaseSource : sources) { - - logger.debug("Database source is " + databaseSource); - Source name = databaseSource.getName(); - String groupName = getGroupNameOnCkan(name.toString().trim()); - if(!groups.contains(groupName)) - groups.add(groupName); - - } + logger.info("Groups is " + groups); } /** @@ -181,15 +170,18 @@ public abstract class HelperMethods { String keyField = field.getAnnotation(CustomField.class).key(); if(f != null){ - if(f.getClass().isArray()){ - if(Collection.class.isAssignableFrom(f.getClass())){ + if(f instanceof List){ + + logger.debug("The object " + field.getName() + " is a list and is annotated with @CustomField. Adding ..."); + List asList = (List)f; + List res = new ArrayList(); + for (Object object : asList) { + logger.debug(object.toString().trim()); + res.add(object.toString().trim()); + } - logger.debug("The object " + field.getName() + " is a collection"); - List res = (List)f; - extras.put(keyField, res); + extras.put(keyField, res); - }else - logger.error("The object " + field.getName() + " cannot be convert to a list/array"); }else{ List values = new ArrayList(); if(extras.containsKey(keyField)) @@ -206,6 +198,8 @@ public abstract class HelperMethods { } } while((current = current.getSuperclass())!=null); + + logger.info("Extras is " + extras); } /** @@ -269,8 +263,8 @@ public abstract class HelperMethods { try(CloseableHttpClient client = HttpClientBuilder.create().build();){ String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath(); - String url = baseUrl.replace("http", "https") + "/users/getUserEmail?gcube-token=" + token; - logger.debug("Request url is " + baseUrl); + String url = baseUrl + "users/getUserEmail?gcube-token=" + token; + logger.debug("Request url is " + url); HttpGet getRequest = new HttpGet(url); HttpResponse response = client.execute(getRequest); @@ -310,7 +304,7 @@ public abstract class HelperMethods { try(CloseableHttpClient client = HttpClientBuilder.create().build();){ String baseUrl = new ServiceEndPointReaderSocial(context).getBasePath(); - String url = baseUrl.replace("http", "https") + "/users/getUserEmail?gcube-token=" + token; + String url = baseUrl + "users/getUserFullname?gcube-token=" + token; logger.debug("Request url is " + url); HttpGet getRequest = new HttpGet(url); HttpResponse response = client.execute(getRequest); @@ -365,9 +359,16 @@ public abstract class HelperMethods { */ public static boolean existsLicenseId(String license) throws Exception { - Map licenses = getLicenses(); - return licenses.containsKey(license); + String scope = ScopeProvider.instance.get(); + DataCatalogue catalogue = getDataCatalogueRunningInstance(scope); + List licenses = catalogue.getLicenses(); + for (CkanLicense ckanLicense : licenses) { + if(ckanLicense.getId().equals(license)) + return true; + } + + return false; } /** @@ -380,15 +381,12 @@ public abstract class HelperMethods { */ public static List getResourcesFromBean(Common record, String username, List tags, List groups){ List toReturn = new ArrayList(); - - List databaseSources = record.getDatabaseSources(); - - // transform database sources - for (DatabaseSource res : databaseSources) { - logger.debug("Adding resource " + res); - toReturn.add(new ResourceBean(res.getUrl(), res.getName().getOrigName(), res.getDescription(), null, username, null, null)); + + List> databaseSources = record.getDatabaseSources(); + for (Resource resource : databaseSources) { + toReturn.add(new ResourceBean(resource.getUrl(), resource.getName().toString(), resource.getDescription(), null, username, null, null)); } - + Class current = record.getClass(); do{ Field[] fields = current.getDeclaredFields(); @@ -403,18 +401,15 @@ public abstract class HelperMethods { List listOfResources = (List)f; for (Resource resource : listOfResources) { - toReturn.add(new ResourceBean(resource.getUrl(), resource.getName(), resource.getDescription(), null, username, null, null)); + toReturn.add(new ResourceBean(resource.getUrl(), resource.getName().toString(), resource.getDescription(), null, username, null, null)); } }else{ Resource res = (Resource)f; - toReturn.add(new ResourceBean(res.getUrl(), res.getName(), res.getDescription(), null, username, null, null)); + toReturn.add(new ResourceBean(res.getUrl(), res.getName().toString(), res.getDescription(), null, username, null, null)); } - - // TODO handle groups/tags - } }catch(Exception e){ logger.error("Failed ot read value for field " + field.getName() + " skipping", e); @@ -424,18 +419,7 @@ public abstract class HelperMethods { } while((current = current.getSuperclass())!=null); - - logger.debug("Returning resources " + toReturn); + logger.info("Returning resources " + toReturn); return toReturn; } - - /** - * Inspect a resource file at this url for finding out tags/groups of the object - * @param r - */ - public static void inspectResourceFile(Resource r){ - - // TODO - - } } diff --git a/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JJerseyTest.java b/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JJerseyTest.java index 101c1ed..080fc1c 100644 --- a/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JJerseyTest.java +++ b/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JJerseyTest.java @@ -7,12 +7,12 @@ import javax.ws.rs.core.Application; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.gcube.data_catalogue.grsf_publish_ws.json.input.DatabaseSource; import org.gcube.data_catalogue.grsf_publish_ws.json.input.FisheryRecord; import org.gcube.data_catalogue.grsf_publish_ws.json.input.Resource; import org.gcube.data_catalogue.grsf_publish_ws.json.input.StockRecord; import org.gcube.data_catalogue.grsf_publish_ws.services.GrsfPublisherFisheryService; import org.gcube.data_catalogue.grsf_publish_ws.services.GrsfPublisherStockService; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Type; import org.glassfish.jersey.server.ResourceConfig; @@ -35,8 +35,8 @@ public class JJerseyTest extends JerseyTest{ recordFishery.setLicense("a caso una lincense"); recordFishery.setDataOwner("data owner"); recordFishery.setType(Type.Fishing_Description); - recordFishery.setDatabaseSources(new ArrayList(1)); - recordFishery.setSourceOfInformation(new ArrayList(1)); + recordFishery.setDatabaseSources(new ArrayList>(1)); + recordFishery.setSourceOfInformation(new ArrayList>(1)); recordFishery.setStatus(Status.Pending); Response res = target("fishery").path("/publish-product").request().post(Entity.entity(recordFishery, MediaType.APPLICATION_JSON)); System.out.println("Result is " + res.readEntity(String.class)); diff --git a/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java b/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java index fa4495d..05b00ae 100644 --- a/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java +++ b/src/test/java/org/gcube/data_catalogue/grsf_publish_ws/JTests.java @@ -16,13 +16,15 @@ import java.util.Map; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.CustomField; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Group; import org.gcube.data_catalogue.grsf_publish_ws.custom_annotations.Tag; -import org.gcube.data_catalogue.grsf_publish_ws.json.input.DatabaseSource; import org.gcube.data_catalogue.grsf_publish_ws.json.input.FisheryRecord; +import org.gcube.data_catalogue.grsf_publish_ws.json.input.Resource; import org.gcube.data_catalogue.grsf_publish_ws.json.input.StockRecord; import org.gcube.data_catalogue.grsf_publish_ws.utils.HelperMethods; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Abundance_Level; +import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Source; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Status; import org.gcube.data_catalogue.grsf_publish_ws.utils.groups.Type; +import org.junit.Test; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonProcessingException; @@ -43,7 +45,7 @@ public class JTests { FisheryRecord recordFishery = new FisheryRecord(); recordFishery.setType(Type.Fishing_Description); - recordFishery.setDatabaseSources(new ArrayList()); + recordFishery.setDatabaseSources(new ArrayList>()); recordFishery.setStatus(Status.Pending); List tags = new ArrayList(); @@ -117,7 +119,7 @@ public class JTests { System.out.println(res.name()); } - //@Test + // @Test public void testJSONMapping() throws IOException{ FisheryRecord record = new FisheryRecord(); @@ -188,7 +190,7 @@ public class JTests { ObjectMapper mapper = new ObjectMapper(); //Object to JSON in String - String jsonInString = mapper.writeValueAsString(record); + StockRecord jsonInString = mapper.readValue("{\n \"short_title\":\"Thunnus maccoyii SEAFO division D.1\",\n \"data_owner\":\"CCSBT\",\n \"narrative_state_and_trend\":\"

The 2014 assessment suggested that the SBT spawning biomass is at a very low fraction (9%) of its original biomass as well as below the level that could produce maximum sustainable yield. However, there has been some improvement since the 2011 stock assessment and the fishing mortality rate is below the level associated with MSY.  The current TAC has been set using the management procedure adopted in 2011, which has a 70% probability of rebuilding to the interim target biomass level by 2035.<\\/p>\",\n \"database_sources\":[\n {\n \"name\":\"firms\",\n \"description\":\"unknown\",\n \"url\":\"unkown\"\n },\n {\n \"name\":\"fishsource\",\n \"description\":\"unknown\",\n \"url\":\"unkown\"\n }\n ],\n \"reporting_year\":2015,\n \"stock_name\":\"Southern Bluefin tuna - Global Name\",\n \"assessment_methods\":\"Survey index\",\n \"abundance_level\":[\n {\n \"year\":2014,\n \"value\":\"low abundance\"\n },\n {\n \"year\":2015,\n \"value\":\"intermediate abundance\"\n }\n ],\n \"abundance_level_for_grouping\":\"low abundance\",\n \"scientific_advice\":\"

Based on the results of the MP operation for 2015–17 in its 2013 meeting and the outcome of the review of exceptional circumstances in its 2015 meeting, the ESC recommended that there is no need to revise the Extended Commission’s 2013 TAC decision regarding the TAC for 2016–17. The recommended annual TAC for the years 2016-2017 is 14,647.4t.<\\/p>\",\n \"type\":\"assessment unit\",\n \"stock_id\":\"Southern Bluefin tuna - Global Title\",\n \"uuid_knowledge_base\":\"c898163b-1dbe-4b97-ba4a-5a73e8b81db9\",\n \"traceability_flag\":true,\n \"water_area\":[\n \"SEAFO division B.1\",\n \"SEAFO division D.0\",\n \"Indian Ocean, East \\/ 57.6\",\n \"SEAFO division D.1\",\n \"Cape of Good Hope\",\n \"Indian Ocean, West \\/ 51.6\",\n \"Indian Ocean, West \\/ 51.7\"\n ],\n \"assessment_distribution_area\":\"an area\",\n \"stock_uri\":\"http:\\/\\/www.bluebridge.com\\/grsf\\/stock\\/c898163b-1dbe-4b97-ba4a-5a73e8b81db9\",\n \"exploiting_fishery\":\"Tunas and billfishes fishery\",\n \"exploitation_rate\":[\n {\n \"year\":2014,\n \"value\":\"moderate fishing mortality\"\n },\n {\n \"year\":2015,\n \"value\":\"high fishing mortality\"\n }\n ],\n \"exploitation_rate_for_grouping\":\"No or low fishing mortality\",\n \"state_of_marine_resource\":\"Overexploited\",\n \"species_scientific_name\":\"Thunnus maccoyii\",\n \"source_of_information\":[\n {\n \"name\":\"sourcename\",\n \"description\":\"unknown\",\n \"url\":\"https:\\/\\/www.ccsbt.org\\/userfiles\\/file\\/docs_english\\/meetings\\/meeting_reports\\/ccsbt_22\\/report_of_SC20.pdf\"\n },\n {\n \"name\":\"sourcename\",\n \"description\":\"unknown\",\n \"url\":\"https:\\/\\/www.ccsbt.org\\/userfiles\\/file\\/docs_english\\/meetings\\/meeting_reports\\/ccsbt_22\\/report_of_SC20-2.pdf\"\n }\n ],\n \"status\":\"pending\",\n \"catches_or_landings\":{\n \"name\":\"catches_or_landings_example\",\n \"description\":\"unknown\",\n \"url\":\"a url\"\n }\n}", StockRecord.class); System.out.println(jsonInString);