mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 18:14:26 +00:00
71752: /metadatafield/<exactMdString> replace with byfieldName?exactName endpoint + tests
This commit is contained in:
@@ -1,68 +0,0 @@
|
|||||||
/**
|
|
||||||
* The contents of this file are subject to the license and copyright
|
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
||||||
* tree and available online at
|
|
||||||
*
|
|
||||||
* http://www.dspace.org/license/
|
|
||||||
*/
|
|
||||||
package org.dspace.app.rest;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.dspace.app.rest.converter.ConverterService;
|
|
||||||
import org.dspace.app.rest.model.MetadataFieldRest;
|
|
||||||
import org.dspace.app.rest.utils.ContextUtil;
|
|
||||||
import org.dspace.app.rest.utils.Utils;
|
|
||||||
import org.dspace.content.MetadataField;
|
|
||||||
import org.dspace.content.service.MetadataFieldService;
|
|
||||||
import org.dspace.core.Context;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This controller will handle all the incoming calls on the /api/core/metadatafields/name/<:metadata-field-full-name>
|
|
||||||
* endpoint where the metadata-field-full-name parameter can be filled in to match a specific metadata field by name
|
|
||||||
* There's always at most one metadata field per name.
|
|
||||||
* <p>
|
|
||||||
* It responds with:
|
|
||||||
* <p>
|
|
||||||
* The single metadata field if there's a match
|
|
||||||
* 404 if the metadata field doesn't exist
|
|
||||||
*
|
|
||||||
* @author Maria Verdonck (Atmire) on 17/07/2020
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/" + MetadataFieldRest.CATEGORY + "/" + MetadataFieldRest.NAME_PLURAL)
|
|
||||||
public class MetadataFieldNameRestController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ConverterService converter;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MetadataFieldService metadataFieldService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Utils utils;
|
|
||||||
|
|
||||||
@GetMapping("/name/{metadata-field-full-name}")
|
|
||||||
public MetadataFieldRest get(HttpServletRequest request, HttpServletResponse response,
|
|
||||||
@PathVariable("metadata-field-full-name") String mdFieldName) {
|
|
||||||
Context context = ContextUtil.obtainContext(request);
|
|
||||||
try {
|
|
||||||
MetadataField metadataField = metadataFieldService.findByString(context, mdFieldName, '.');
|
|
||||||
|
|
||||||
if (metadataField == null) {
|
|
||||||
throw new ResourceNotFoundException("There was no metadata field found with name: " + mdFieldName);
|
|
||||||
}
|
|
||||||
return converter.toRest(metadataField, utils.obtainProjection());
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -120,6 +120,9 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
|||||||
* @param qualifierName an exact match of the field's qualifier (e.g. "author", "alternative")
|
* @param qualifierName an exact match of the field's qualifier (e.g. "author", "alternative")
|
||||||
* @param query part of the fully qualified field, should start with the start of the schema, element or
|
* @param query part of the fully qualified field, should start with the start of the schema, element or
|
||||||
* qualifier (e.g. "dc.ti", "contributor", "auth", "contributor.ot")
|
* qualifier (e.g. "dc.ti", "contributor", "auth", "contributor.ot")
|
||||||
|
* @param exactName exactName, The exact fully qualified field, should use the syntax schema.element
|
||||||
|
* .qualifier or schema.element if no qualifier exists (e.g. "dc.title", "dc.contributor
|
||||||
|
* .author"). It will only return one value if there's an exact match
|
||||||
* @param pageable the pagination options
|
* @param pageable the pagination options
|
||||||
* @return List of {@link MetadataFieldRest} objects representing all {@link MetadataField} objects that match
|
* @return List of {@link MetadataFieldRest} objects representing all {@link MetadataField} objects that match
|
||||||
* the given params
|
* the given params
|
||||||
@@ -129,12 +132,15 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
|||||||
@Parameter(value = "element", required = false) String elementName,
|
@Parameter(value = "element", required = false) String elementName,
|
||||||
@Parameter(value = "qualifier", required = false) String qualifierName,
|
@Parameter(value = "qualifier", required = false) String qualifierName,
|
||||||
@Parameter(value = "query", required = false) String query,
|
@Parameter(value = "query", required = false) String query,
|
||||||
|
@Parameter(value = "exactName", required = false) String exactName,
|
||||||
Pageable pageable) throws SQLException {
|
Pageable pageable) throws SQLException {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
DiscoverQuery discoverQuery = this.createDiscoverQuery(context, schemaName, elementName, qualifierName, query);
|
|
||||||
|
|
||||||
List<MetadataField> matchingMetadataFields = new ArrayList<>();
|
List<MetadataField> matchingMetadataFields = new ArrayList<>();
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(exactName)) {
|
||||||
|
// Find matches in Solr Search core
|
||||||
|
DiscoverQuery discoverQuery = this.createDiscoverQuery(context, schemaName, elementName, qualifierName, query);
|
||||||
try {
|
try {
|
||||||
DiscoverResult searchResult = searchService.search(context, null, discoverQuery);
|
DiscoverResult searchResult = searchService.search(context, null, discoverQuery);
|
||||||
for (IndexableObject object : searchResult.getIndexableObjects()) {
|
for (IndexableObject object : searchResult.getIndexableObjects()) {
|
||||||
@@ -146,6 +152,13 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
|||||||
log.error("Error while searching with Discovery", e);
|
log.error("Error while searching with Discovery", e);
|
||||||
throw new IllegalArgumentException("Error while searching with Discovery: " + e.getMessage());
|
throw new IllegalArgumentException("Error while searching with Discovery: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Find at most one match with exactName query param in DB
|
||||||
|
MetadataField exactMatchingMdField = metadataFieldService.findByString(context, exactName, '.');
|
||||||
|
if (exactMatchingMdField != null) {
|
||||||
|
matchingMetadataFields.add(exactMatchingMdField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return converter.toRestPage(matchingMetadataFields, pageable, utils.obtainProjection());
|
return converter.toRestPage(matchingMetadataFields, pageable, utils.obtainProjection());
|
||||||
}
|
}
|
||||||
@@ -297,8 +310,10 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
|||||||
context.commit();
|
context.commit();
|
||||||
} catch (NonUniqueMetadataException e) {
|
} catch (NonUniqueMetadataException e) {
|
||||||
throw new UnprocessableEntityException("metadata field "
|
throw new UnprocessableEntityException("metadata field "
|
||||||
+ metadataField.getMetadataSchema().getName() + "." + metadataFieldRest.getElement()
|
+ metadataField.getMetadataSchema().getName() + "." +
|
||||||
+ (metadataFieldRest.getQualifier() != null ? "." + metadataFieldRest.getQualifier() : "")
|
metadataFieldRest.getElement()
|
||||||
|
+ (metadataFieldRest.getQualifier() != null ?
|
||||||
|
"." + metadataFieldRest.getQualifier() : "")
|
||||||
+ " already exists");
|
+ " already exists");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* The contents of this file are subject to the license and copyright
|
|
||||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
|
||||||
* tree and available online at
|
|
||||||
*
|
|
||||||
* http://www.dspace.org/license/
|
|
||||||
*/
|
|
||||||
package org.dspace.app.rest;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
||||||
|
|
||||||
import org.dspace.app.rest.builder.MetadataFieldBuilder;
|
|
||||||
import org.dspace.app.rest.builder.MetadataSchemaBuilder;
|
|
||||||
import org.dspace.app.rest.test.AbstractEntityIntegrationTest;
|
|
||||||
import org.dspace.content.MetadataField;
|
|
||||||
import org.dspace.content.MetadataSchema;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Integration tests for the {@link org.dspace.app.rest.MetadataFieldNameRestController} controlled endpoints
|
|
||||||
*
|
|
||||||
* @author Maria Verdonck (Atmire) on 17/07/2020
|
|
||||||
*/
|
|
||||||
public class MetadataFieldNameRestControllerIT extends AbstractEntityIntegrationTest {
|
|
||||||
|
|
||||||
private static final String GETBYNAME_METADATAFIELDS_ENDPOINT =
|
|
||||||
MetadatafieldRestRepositoryIT.METADATAFIELDS_ENDPOINT + "name/";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetMetadataFieldByName_ExistingName() throws Exception {
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
MetadataSchema schema = MetadataSchemaBuilder.createMetadataSchema(context, "ASchema",
|
|
||||||
"http://www.dspace.org/ns/aschema").build();
|
|
||||||
|
|
||||||
MetadataField metadataField = MetadataFieldBuilder
|
|
||||||
.createMetadataField(context, schema, "AnElement1", "AQualifier", "AScopeNote").build();
|
|
||||||
|
|
||||||
context.restoreAuthSystemState();
|
|
||||||
getClient().perform(get(GETBYNAME_METADATAFIELDS_ENDPOINT + metadataField.toString('.')))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.id", is(metadataField.getID())))
|
|
||||||
.andExpect(jsonPath("$.element", is(metadataField.getElement())));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetMetadataFieldByName_ExistingName_NoQualifier() throws Exception {
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
MetadataSchema schema = MetadataSchemaBuilder.createMetadataSchema(context, "ASchema",
|
|
||||||
"http://www.dspace.org/ns/aschema").build();
|
|
||||||
|
|
||||||
MetadataField metadataField = MetadataFieldBuilder
|
|
||||||
.createMetadataField(context, schema, "AnElement1", null, "AScopeNote").build();
|
|
||||||
|
|
||||||
context.restoreAuthSystemState();
|
|
||||||
getClient().perform(get(GETBYNAME_METADATAFIELDS_ENDPOINT + metadataField.toString('.')))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.id", is(metadataField.getID())))
|
|
||||||
.andExpect(jsonPath("$.element", is(metadataField.getElement())))
|
|
||||||
.andExpect(jsonPath("$.qualifier", is(metadataField.getQualifier())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetMetadataFieldByName_NonExistentName() throws Exception {
|
|
||||||
String nonExistentName = "nonExistentName";
|
|
||||||
getClient().perform(get(GETBYNAME_METADATAFIELDS_ENDPOINT + nonExistentName))
|
|
||||||
.andExpect(status().isNotFound());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -447,6 +447,70 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
|
|||||||
.andExpect(jsonPath("$.page.totalElements", is(2)));
|
.andExpect(jsonPath("$.page.totalElements", is(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByFieldName_query_exactName() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
MetadataSchema schema = MetadataSchemaBuilder.createMetadataSchema(context, "ASchema",
|
||||||
|
"http://www.dspace.org/ns/aschema").build();
|
||||||
|
MetadataSchema schema2 = MetadataSchemaBuilder.createMetadataSchema(context, "test",
|
||||||
|
"http://www.dspace.org/ns/aschema2").build();
|
||||||
|
|
||||||
|
MetadataField metadataField = MetadataFieldBuilder
|
||||||
|
.createMetadataField(context, schema, "AnElement1", null, "AScopeNote").build();
|
||||||
|
|
||||||
|
MetadataField metadataField2 = MetadataFieldBuilder
|
||||||
|
.createMetadataField(context, schema2, "AnElement2", null, "AScopeNote2").build();
|
||||||
|
|
||||||
|
MetadataField metadataField3 = MetadataFieldBuilder
|
||||||
|
.createMetadataField(context, schema, "test", null, "AScopeNote2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(get(SEARCH_BYFIELDNAME_ENDPOINT)
|
||||||
|
.param("exactName", metadataField.toString('.')))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItem(
|
||||||
|
MetadataFieldMatcher.matchMetadataField(metadataField))
|
||||||
|
))
|
||||||
|
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.not(hasItem(
|
||||||
|
MetadataFieldMatcher.matchMetadataField(metadataField3))
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.not(hasItem(
|
||||||
|
MetadataFieldMatcher.matchMetadataField(metadataField2))
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$.page.size", is(20)))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findByFieldName_query_exactName_NoResult() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
MetadataSchema schema = MetadataSchemaBuilder.createMetadataSchema(context, "ASchema",
|
||||||
|
"http://www.dspace.org/ns/aschema").build();
|
||||||
|
MetadataSchema schema2 = MetadataSchemaBuilder.createMetadataSchema(context, "test",
|
||||||
|
"http://www.dspace.org/ns/aschema2").build();
|
||||||
|
|
||||||
|
MetadataField metadataField = MetadataFieldBuilder
|
||||||
|
.createMetadataField(context, schema, "AnElement1", null, "AScopeNote").build();
|
||||||
|
|
||||||
|
MetadataField metadataField2 = MetadataFieldBuilder
|
||||||
|
.createMetadataField(context, schema2, "AnElement2", null, "AScopeNote2").build();
|
||||||
|
|
||||||
|
MetadataField metadataField3 = MetadataFieldBuilder
|
||||||
|
.createMetadataField(context, schema, "test", null, "AScopeNote2").build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
getClient().perform(get(SEARCH_BYFIELDNAME_ENDPOINT)
|
||||||
|
.param("exactName", "not.valid.mdstring"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findByFieldName_invalidQuery() throws Exception {
|
public void findByFieldName_invalidQuery() throws Exception {
|
||||||
getClient().perform(get(SEARCH_BYFIELDNAME_ENDPOINT)
|
getClient().perform(get(SEARCH_BYFIELDNAME_ENDPOINT)
|
||||||
|
Reference in New Issue
Block a user