mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +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 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")
|
||||
* @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
|
||||
* @return List of {@link MetadataFieldRest} objects representing all {@link MetadataField} objects that match
|
||||
* the given params
|
||||
@@ -129,22 +132,32 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
||||
@Parameter(value = "element", required = false) String elementName,
|
||||
@Parameter(value = "qualifier", required = false) String qualifierName,
|
||||
@Parameter(value = "query", required = false) String query,
|
||||
@Parameter(value = "exactName", required = false) String exactName,
|
||||
Pageable pageable) throws SQLException {
|
||||
Context context = obtainContext();
|
||||
DiscoverQuery discoverQuery = this.createDiscoverQuery(context, schemaName, elementName, qualifierName, query);
|
||||
|
||||
List<MetadataField> matchingMetadataFields = new ArrayList<>();
|
||||
|
||||
try {
|
||||
DiscoverResult searchResult = searchService.search(context, null, discoverQuery);
|
||||
for (IndexableObject object : searchResult.getIndexableObjects()) {
|
||||
if (object instanceof IndexableMetadataField) {
|
||||
matchingMetadataFields.add(((IndexableMetadataField) object).getIndexedObject());
|
||||
if (StringUtils.isBlank(exactName)) {
|
||||
// Find matches in Solr Search core
|
||||
DiscoverQuery discoverQuery = this.createDiscoverQuery(context, schemaName, elementName, qualifierName, query);
|
||||
try {
|
||||
DiscoverResult searchResult = searchService.search(context, null, discoverQuery);
|
||||
for (IndexableObject object : searchResult.getIndexableObjects()) {
|
||||
if (object instanceof IndexableMetadataField) {
|
||||
matchingMetadataFields.add(((IndexableMetadataField) object).getIndexedObject());
|
||||
}
|
||||
}
|
||||
} catch (SearchServiceException e) {
|
||||
log.error("Error while searching with Discovery", e);
|
||||
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);
|
||||
}
|
||||
} catch (SearchServiceException e) {
|
||||
log.error("Error while searching with Discovery", e);
|
||||
throw new IllegalArgumentException("Error while searching with Discovery: " + e.getMessage());
|
||||
}
|
||||
|
||||
return converter.toRestPage(matchingMetadataFields, pageable, utils.obtainProjection());
|
||||
@@ -202,15 +215,15 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
protected MetadataFieldRest createAndReturn(Context context)
|
||||
throws AuthorizeException, SQLException {
|
||||
throws AuthorizeException, SQLException {
|
||||
|
||||
// parse request body
|
||||
MetadataFieldRest metadataFieldRest;
|
||||
try {
|
||||
metadataFieldRest = new ObjectMapper().readValue(
|
||||
getRequestService().getCurrentRequest().getHttpServletRequest().getInputStream(),
|
||||
MetadataFieldRest.class
|
||||
);
|
||||
getRequestService().getCurrentRequest().getHttpServletRequest().getInputStream(),
|
||||
MetadataFieldRest.class
|
||||
);
|
||||
} catch (IOException excIO) {
|
||||
throw new DSpaceBadRequestException("error parsing request body", excIO);
|
||||
}
|
||||
@@ -234,14 +247,14 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
||||
MetadataField metadataField;
|
||||
try {
|
||||
metadataField = metadataFieldService.create(context, schema,
|
||||
metadataFieldRest.getElement(), metadataFieldRest.getQualifier(), metadataFieldRest.getScopeNote());
|
||||
metadataFieldRest.getElement(), metadataFieldRest.getQualifier(), metadataFieldRest.getScopeNote());
|
||||
metadataFieldService.update(context, metadataField);
|
||||
} catch (NonUniqueMetadataException e) {
|
||||
throw new UnprocessableEntityException(
|
||||
"metadata field "
|
||||
+ schema.getName() + "." + metadataFieldRest.getElement()
|
||||
+ (metadataFieldRest.getQualifier() != null ? "." + metadataFieldRest.getQualifier() : "")
|
||||
+ " already exists"
|
||||
"metadata field "
|
||||
+ schema.getName() + "." + metadataFieldRest.getElement()
|
||||
+ (metadataFieldRest.getQualifier() != null ? "." + metadataFieldRest.getQualifier() : "")
|
||||
+ " already exists"
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -271,7 +284,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
protected MetadataFieldRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
||||
Integer id, JsonNode jsonNode) throws SQLException, AuthorizeException {
|
||||
Integer id, JsonNode jsonNode) throws SQLException, AuthorizeException {
|
||||
|
||||
MetadataFieldRest metadataFieldRest = new Gson().fromJson(jsonNode.toString(), MetadataFieldRest.class);
|
||||
|
||||
@@ -297,9 +310,11 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
||||
context.commit();
|
||||
} catch (NonUniqueMetadataException e) {
|
||||
throw new UnprocessableEntityException("metadata field "
|
||||
+ metadataField.getMetadataSchema().getName() + "." + metadataFieldRest.getElement()
|
||||
+ (metadataFieldRest.getQualifier() != null ? "." + metadataFieldRest.getQualifier() : "")
|
||||
+ " already exists");
|
||||
+ metadataField.getMetadataSchema().getName() + "." +
|
||||
metadataFieldRest.getElement()
|
||||
+ (metadataFieldRest.getQualifier() != null ?
|
||||
"." + metadataFieldRest.getQualifier() : "")
|
||||
+ " already exists");
|
||||
} catch (IOException 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)));
|
||||
}
|
||||
|
||||
@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
|
||||
public void findByFieldName_invalidQuery() throws Exception {
|
||||
getClient().perform(get(SEARCH_BYFIELDNAME_ENDPOINT)
|
||||
|
Reference in New Issue
Block a user