Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVOC : allow flexible params in retrievalUri (Ontoportal integration) #10404

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
## Release Highlights

### Updates on Support for External Vocabulary Services

#### HTTP Headers

You are now able to add HTTP request headers required by the service you are implementing (#10331)

#### Flexible params in retrievalUri

You can now use `managed-fields` field names as well as the `term-uri-field` field name as parameters in the `retrieval-uri` when configuring an external vocabulary service. `{0}` as an alternative to using the `term-uri-field` name is still supported for backward compatibility.
Also you can specify if the value must be url encoded with `encodeUrl:`. (#10404)

For example : `"retrieval-uri": "https://data.agroportal.lirmm.fr/ontologies/{keywordVocabulary}/classes/{encodeUrl:keywordTermURL}"`
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.text.MessageFormat;
Expand Down Expand Up @@ -349,8 +350,12 @@ public void registerExternalVocabValues(DatasetField df) {
logger.fine("Registering for field: " + dft.getName());
JsonObject cvocEntry = getCVocConf(true).get(dft.getId());
if (dft.isPrimitive()) {
List<DatasetField> siblingsDatasetFields = new ArrayList<>();
if(dft.getParentDatasetFieldType()!=null) {
siblingsDatasetFields = df.getParentDatasetFieldCompoundValue().getChildDatasetFields();
}
for (DatasetFieldValue dfv : df.getDatasetFieldValues()) {
registerExternalTerm(cvocEntry, dfv.getValue());
registerExternalTerm(cvocEntry, dfv.getValue(), siblingsDatasetFields);
}
} else {
if (df.getDatasetFieldType().isCompound()) {
Expand All @@ -359,7 +364,7 @@ public void registerExternalVocabValues(DatasetField df) {
for (DatasetField cdf : cv.getChildDatasetFields()) {
logger.fine("Found term uri field type id: " + cdf.getDatasetFieldType().getId());
if (cdf.getDatasetFieldType().equals(termdft)) {
registerExternalTerm(cvocEntry, cdf.getValue());
registerExternalTerm(cvocEntry, cdf.getValue(), cv.getChildDatasetFields());
}
}
}
Expand Down Expand Up @@ -447,15 +452,17 @@ public JsonObject getExternalVocabularyValue(String termUri) {

/**
* Perform a call to the external service to retrieve information about the term URI
* @param cvocEntry - the configuration for the DatasetFieldType associated with this term
* @param term - the term uri as a string
*
* @param cvocEntry - the configuration for the DatasetFieldType associated with this term
* @param term - the term uri as a string
* @param relatedDatasetFields - siblings or childs of the term
*/
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void registerExternalTerm(JsonObject cvocEntry, String term) {
public void registerExternalTerm(JsonObject cvocEntry, String term, List<DatasetField> relatedDatasetFields) {
String retrievalUri = cvocEntry.getString("retrieval-uri");
String termUriFieldName = cvocEntry.getString("term-uri-field");
String prefix = cvocEntry.getString("prefix", null);
if(term.isBlank()) {
logger.fine("Ingoring blank term");
logger.fine("Ignoring blank term");
return;
}
boolean isExternal = false;
Expand Down Expand Up @@ -486,7 +493,13 @@ public void registerExternalTerm(JsonObject cvocEntry, String term) {
}
if (evv.getValue() == null) {
String adjustedTerm = (prefix==null)? term: term.replace(prefix, "");
retrievalUri = retrievalUri.replace("{0}", adjustedTerm);

retrievalUri = replaceRetrievalUriParam(retrievalUri, "0", adjustedTerm);
retrievalUri = replaceRetrievalUriParam(retrievalUri, termUriFieldName, adjustedTerm);
for (DatasetField f : relatedDatasetFields) {
retrievalUri = replaceRetrievalUriParam(retrievalUri, f.getDatasetFieldType().getName(), f.getValue());
}

logger.fine("Didn't find " + term + ", calling " + retrievalUri);
try (CloseableHttpClient httpClient = HttpClients.custom()
.addInterceptorLast(new HttpResponseInterceptor() {
Expand Down Expand Up @@ -546,6 +559,17 @@ public void process(HttpResponse response, HttpContext context) throws HttpExcep

}

private String replaceRetrievalUriParam(String retrievalUri, String paramName, String value) {

if(retrievalUri.contains("encodeUrl:" + paramName)) {
retrievalUri = retrievalUri.replace("{encodeUrl:"+paramName+"}", URLEncoder.encode(value, StandardCharsets.UTF_8));
} else {
retrievalUri = retrievalUri.replace("{"+paramName+"}", value);
}

return retrievalUri;
}

/**
* Parse the raw value returned by an external service for a give term uri and
* filter it according to the 'retrieval-filtering' configuration for this
Expand Down
6 changes: 0 additions & 6 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3932,12 +3932,6 @@ public String save() {
((UpdateDatasetVersionCommand) cmd).setValidateLenient(true);
}
dataset = commandEngine.submit(cmd);
for (DatasetField df : dataset.getLatestVersion().getFlatDatasetFields()) {
logger.fine("Found id: " + df.getDatasetFieldType().getId());
if (fieldService.getCVocConf(true).containsKey(df.getDatasetFieldType().getId())) {
fieldService.registerExternalVocabValues(df);
}
}
if (editMode == EditMode.CREATE) {
if (session.getUser() instanceof AuthenticatedUser) {
userNotificationService.sendNotification((AuthenticatedUser) session.getUser(), dataset.getCreateDate(), UserNotification.Type.CREATEDS, dataset.getLatestVersion().getId());
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ public class EjbDataverseEngine {
@EJB
DatasetLinkingServiceBean dsLinking;

@EJB
DatasetFieldServiceBean dsField;

@EJB
ExplicitGroupServiceBean explicitGroups;

Expand Down Expand Up @@ -509,7 +512,12 @@ public DataverseLinkingServiceBean dvLinking() {
public DatasetLinkingServiceBean dsLinking() {
return dsLinking;
}


@Override
public DatasetFieldServiceBean dsField() {
return dsField;
}

@Override
public StorageUseServiceBean storageUse() {
return storageUseService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.harvard.iq.dataverse.engine.command;

import edu.harvard.iq.dataverse.DataFileServiceBean;
import edu.harvard.iq.dataverse.DatasetFieldServiceBean;
import edu.harvard.iq.dataverse.DatasetLinkingServiceBean;
import edu.harvard.iq.dataverse.DatasetServiceBean;
import edu.harvard.iq.dataverse.DatasetVersionServiceBean;
Expand Down Expand Up @@ -146,4 +147,6 @@ public interface CommandContext {
public Stack<Command> getCommandsCalled();

public void addCommand(Command command);

public DatasetFieldServiceBean dsField();
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
package edu.harvard.iq.dataverse.engine.command.impl;

import edu.harvard.iq.dataverse.*;
import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.batch.util.LoggingUtil;
import edu.harvard.iq.dataverse.dataaccess.DataAccess;
import edu.harvard.iq.dataverse.datacapturemodule.DataCaptureModuleUtil;
import edu.harvard.iq.dataverse.datacapturemodule.ScriptRequestResponse;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.exception.CommandExecutionException;
import edu.harvard.iq.dataverse.pidproviders.PidProvider;
import edu.harvard.iq.dataverse.pidproviders.PidUtil;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import static edu.harvard.iq.dataverse.util.StringUtil.isEmpty;
import java.io.IOException;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.solr.client.solrj.SolrServerException;

/**;
* An abstract base class for commands that creates {@link Dataset}s.
Expand Down Expand Up @@ -97,6 +90,8 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
if(!harvested) {
checkSystemMetadataKeyIfNeeded(dsv, null);
}

registerExternalVocabValuesIfAny(ctxt, dsv);

theDataset.setCreator((AuthenticatedUser) getRequest().getUser());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetField;
import edu.harvard.iq.dataverse.DatasetFieldServiceBean;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DatasetVersionDifference;
import edu.harvard.iq.dataverse.DatasetVersionUser;
import edu.harvard.iq.dataverse.Dataverse;
import edu.harvard.iq.dataverse.MetadataBlock;
import edu.harvard.iq.dataverse.TermsOfUseAndAccess;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.engine.command.AbstractCommand;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
Expand All @@ -24,9 +27,8 @@
import java.util.logging.Logger;
import static java.util.stream.Collectors.joining;

import jakarta.ejb.EJB;
import jakarta.validation.ConstraintViolation;
import edu.harvard.iq.dataverse.MetadataBlock;
import edu.harvard.iq.dataverse.TermsOfUseAndAccess;
import edu.harvard.iq.dataverse.settings.JvmSettings;

/**
Expand Down Expand Up @@ -231,4 +233,13 @@ protected void checkSystemMetadataKeyIfNeeded(DatasetVersion newVersion, Dataset
}
}
}

protected void registerExternalVocabValuesIfAny(CommandContext ctxt, DatasetVersion newVersion) {
for (DatasetField df : newVersion.getFlatDatasetFields()) {
logger.fine("Found id: " + df.getDatasetFieldType().getId());
if (ctxt.dsField().getCVocConf(true).containsKey(df.getDatasetFieldType().getId())) {
ctxt.dsField().registerExternalVocabValues(df);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public DatasetVersion execute(CommandContext ctxt) throws CommandException {
//Will throw an IllegalCommandException if a system metadatablock is changed and the appropriate key is not supplied.
checkSystemMetadataKeyIfNeeded(newVersion, latest);


registerExternalVocabValuesIfAny(ctxt, newVersion);

List<FileMetadata> newVersionMetadatum = new ArrayList<>(latest.getFileMetadatas().size());
for ( FileMetadata fmd : latest.getFileMetadatas() ) {
FileMetadata fmdCopy = fmd.createCopy();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package edu.harvard.iq.dataverse.engine.command.impl;

import edu.harvard.iq.dataverse.*;
import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.DataFileCategory;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetLock;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DatasetVersionDifference;
import edu.harvard.iq.dataverse.FileMetadata;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import edu.harvard.iq.dataverse.util.DatasetFieldUtil;
import edu.harvard.iq.dataverse.util.FileMetadataUtil;

Expand Down Expand Up @@ -115,8 +120,11 @@ public Dataset execute(CommandContext ctxt) throws CommandException {

//Will throw an IllegalCommandException if a system metadatablock is changed and the appropriate key is not supplied.
checkSystemMetadataKeyIfNeeded(getDataset().getOrCreateEditVersion(fmVarMet), persistedVersion);



getDataset().getOrCreateEditVersion().setLastUpdateTime(getTimestamp());

registerExternalVocabValuesIfAny(ctxt, getDataset().getOrCreateEditVersion(fmVarMet));

try {
// Invariant: Dataset has no locks preventing the update
String lockInfoMessage = "saving current edits";
Expand Down Expand Up @@ -256,7 +264,6 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
ctxt.ingest().recalculateDatasetVersionUNF(theDataset.getOrCreateEditVersion());
}

theDataset.getOrCreateEditVersion().setLastUpdateTime(getTimestamp());
theDataset.setModificationTime(getTimestamp());

savedDataset = ctxt.em().merge(theDataset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,6 @@ private static void addField(DatasetField dsf, JsonArray valArray, DatasetFieldT
if(!datasetFieldSvc.isValidCVocValue(dsft, strValue)) {
throw new BadRequestException("Invalid values submitted for " + dsft.getName() + " which is limited to specific vocabularies.");
}
datasetFieldSvc.registerExternalTerm(cvocMap.get(dsft.getId()), strValue);
}
DatasetFieldValue datasetFieldValue = new DatasetFieldValue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,6 @@ public void parsePrimitiveValue(DatasetField dsf, DatasetFieldType dft , JsonObj
if(!datasetFieldSvc.isValidCVocValue(dft, datasetFieldValue.getValue())) {
throw new JsonParseException("Invalid values submitted for " + dft.getName() + " which is limited to specific vocabularies.");
}
datasetFieldSvc.registerExternalTerm(cvocMap.get(dft.getId()), datasetFieldValue.getValue());
}
vals.add(datasetFieldValue);
}
Expand All @@ -864,7 +863,6 @@ public void parsePrimitiveValue(DatasetField dsf, DatasetFieldType dft , JsonObj
if(!datasetFieldSvc.isValidCVocValue(dft, datasetFieldValue.getValue())) {
throw new JsonParseException("Invalid values submitted for " + dft.getName() + " which is limited to specific vocabularies.");
}
datasetFieldSvc.registerExternalTerm(cvocMap.get(dft.getId()), datasetFieldValue.getValue());
}
vals.add(datasetFieldValue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ public DatasetLinkingServiceBean dsLinking() {
return null;
}

@Override
public DatasetFieldServiceBean dsField() {
return null;
}

@Override
public AuthenticationServiceBean authentication() {
return null;
Expand Down
Loading