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

Rest api for handle resolution with metadata #761

Merged
merged 23 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 48 additions & 8 deletions dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,53 @@ public void scanNAs(ScanCallback callback) throws HandleException {
// Resolving methods
////////////////////////////////////////

/**
* Extracts a DSpaceObject based on the given handle.
*
* @param context the context
* @param handle the handle to resolve
* @return the resolved DSpaceObject or null if not resolved
* @throws HandleException if an error occurs during resolution
*/
private static DSpaceObject extractDSpaceObject(Context context, String handle) throws HandleException {
Paurikova2 marked this conversation as resolved.
Show resolved Hide resolved
boolean resolveMetadata = configurationService.getBooleanProperty("lr.pid.resolvemetadata", true);
try {
if (resolveMetadata) {
return handleClarinService.resolveToObject(context, handle);
}
return null;
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("Exception in extractDSpaceObject", e);
}
throw new HandleException(HandleException.INTERNAL_ERROR);
}
}

/**
* Retrieves handle values as a map.
*
* @param handle the handle to resolve
* @return a map containing the handle values
* @throws HandleException if an error occurs during handle resolution
*/
public static Map<String, String> getMapHandleValues(String handle) throws HandleException {
if (log.isInfoEnabled()) {
log.info("Called getMapHandleValues");
}
loadServices();
Context context = new Context();
try {
return extractMetadata(extractDSpaceObject(context, handle));
} finally {
try {
context.complete();
} catch (SQLException sqle) {
// ignore
}
}
}

/**
* Return the raw values for this handle. This implementation returns a
* single URL value.
Expand Down Expand Up @@ -285,15 +332,7 @@ public byte[][] getRawHandleValues(byte[] theHandle, int[] indexList,
String handle = Util.decodeString(theHandle);

context = new Context();

DSpaceObject dso = null;
String url = handleClarinService.resolveToURL(context, handle);

boolean resolveMetadata = configurationService.getBooleanProperty("lr.pid.resolvemetadata", true);
if (resolveMetadata) {
dso = handleClarinService.resolveToObject(context, handle);
}

if (Objects.isNull(url)) {
// try with old prefix

Expand Down Expand Up @@ -332,6 +371,7 @@ public byte[][] getRawHandleValues(byte[] theHandle, int[] indexList,
rh = new ResolvedHandle(url, splits[1], splits[2], splits[3], splits[4], splits[5], splits[6],
splits[7]);
} else {
DSpaceObject dso = extractDSpaceObject(context, handle);
rh = new ResolvedHandle(url, dso);
}
log.info(String.format("Handle [%s] resolved to [%s]", handle, url));
Expand Down
5 changes: 4 additions & 1 deletion dspace-api/src/test/data/dspaceFolder/config/local.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,7 @@ sync.storage.service.enabled = false
signposting.enabled = true

# Test configuration has only EN locale (submission-forms.xml)
webui.supported.locales = en
webui.supported.locales = en

# Test configuration for HdlResolverRestController
milanmajchrak marked this conversation as resolved.
Show resolved Hide resolved
handle.reportemail = [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@
package org.dspace.app.rest.hdlresolver;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.handle.hdllib.HandleException;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.handle.HandlePlugin;
import org.dspace.handle.hdlresolver.HdlResolverDTO;
import org.dspace.handle.hdlresolver.HdlResolverService;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -102,7 +106,7 @@ public ResponseEntity<String> resolveHandle(HttpServletRequest request, String h
if (!handleResolver.isValid()) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} else {
return new ResponseEntity<>(this.resolveToURL(request, handleResolver), HttpStatus.OK);
return new ResponseEntity<>(this.resolveToMtd(request, handleResolver), HttpStatus.OK);
milanmajchrak marked this conversation as resolved.
Show resolved Hide resolved
Paurikova2 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -165,14 +169,42 @@ public ResponseEntity<String> listHandles(HttpServletRequest request, @PathVaria
}

/**
* Maps the handle to a correct response.
* Maps the handle to url.
*
* @param request HttpServletRequest
* @param handleResolver HdlResolverDTO - Handle resolver
* @return One element list using String if found, else null String.
* @return String if found, else null String.
*/
private String resolveToURL(HttpServletRequest request, HdlResolverDTO handleResolver) {
return mapAsJson(this.hdlResolverService.resolveToURL(ContextUtil.obtainContext(request), handleResolver));
vidiecan marked this conversation as resolved.
Show resolved Hide resolved
return this.hdlResolverService.resolveToURL(ContextUtil.obtainContext(request), handleResolver);
}

/**
* Resolves the metadata based on the given request and handle resolver.
*
* @param request the HTTP request containing the metadata parameter
* @param handleResolver the handle resolver containing the handle
* @return a JSON representation of the URL or the handle values map, or "null" in case of an error
*/
private String resolveToMtd(HttpServletRequest request, HdlResolverDTO handleResolver) {
Map<String, String> result = new HashMap<>();
Paurikova2 marked this conversation as resolved.
Show resolved Hide resolved
String url = resolveToURL(request, handleResolver);
String param = request.getParameter("metadata");
if (StringUtils.isBlank(param)) {
return mapAsJson(url);
}
result.put("url", url);
String handle = handleResolver.getHandle();
try {
Map<String, String> metadata = HandlePlugin.getMapHandleValues(handle);
for (Map.Entry<String, String> entry : metadata.entrySet()) {
result.put(entry.getKey().toLowerCase(), entry.getValue());
Paurikova2 marked this conversation as resolved.
Show resolved Hide resolved
}
return mapAsJson(result);
} catch (HandleException e) {
log.error("Failed to resolve handle values for handle: " + handle, e);
}
return "null";
Paurikova2 marked this conversation as resolved.
Show resolved Hide resolved
}

protected String mapAsJson(final String resolvedUrl) {
Expand All @@ -183,6 +215,19 @@ protected String mapAsJson(final String resolvedUrl) {
return json;
}

protected String mapAsJson(final Map<String, String> resolvedMap) {
ObjectMapper objectMapper = new ObjectMapper();
String json = "null";
try {
if (resolvedMap != null && !resolvedMap.isEmpty()) {
json = objectMapper.writeValueAsString(resolvedMap);
}
} catch (JsonProcessingException e) {
log.error("Error during conversion of response!", e);
}
return json;
}

protected String mapAsJson(final List<String> jsonList) {
String json = "null";
if (jsonList != null && !jsonList.isEmpty()) {
Expand All @@ -194,5 +239,4 @@ protected String mapAsJson(final List<String> jsonList) {
}
return json;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
Expand Down Expand Up @@ -84,7 +85,37 @@ public void givenMappedIdentifierWhenCallHdlresolverThenReturnsMappedURL() throw
getClient()
.perform(get("/wrongController/" + publicItem1.getHandle()))
.andExpect(status().isNotFound());
}

@Test
public void givenMappedIdentifierWhenCallHdlresolverThenReturnsMappedParams() throws Exception {
context.turnOffAuthorisationSystem();

// ** START GIVEN **

parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();

Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1")
.withLogo("TestingContentForLogo").build();

Item publicItem1 = ItemBuilder.createItem(context, col1).withTitle("Public item 1").withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John").withSubject("ExtraEntry")
.withHandle("123456789/testHdlResolver").build();

context.restoreAuthSystemState();

// ** END GIVEN **
getClient()
.perform(get(HdlResolverRestController.RESOLVE + publicItem1.getHandle())
.param("metadata", "true"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.url",
StringContains.containsString("123456789/testHdlResolver")))
.andExpect(jsonPath("$.title", StringContains.containsString("Public item 1")))
.andExpect(jsonPath("$.repository", is(configurationService.getProperty("dspace.name"))))
.andExpect(jsonPath("$.reportemail",
StringContains.containsString(configurationService.getProperty("handle.reportemail"))))
milanmajchrak marked this conversation as resolved.
Show resolved Hide resolved
.andExpect(jsonPath("$.submitdate").exists());
}

@Test
Expand Down
Loading