diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserMetadataImportController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserMetadataImportController.java new file mode 100644 index 000000000000..706d538ade74 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserMetadataImportController.java @@ -0,0 +1,230 @@ +/** + * 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.dspace.app.rest.utils.ContextUtil.obtainContext; + +import java.io.IOException; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.NotFoundException; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.Logger; +import org.dspace.app.rest.converter.ConverterService; +import org.dspace.app.rest.model.ClarinUserMetadataRest; +import org.dspace.app.rest.repository.ClarinUserMetadataRestController; +import org.dspace.app.rest.utils.Utils; +import org.dspace.content.clarin.ClarinLicenseResourceMapping; +import org.dspace.content.clarin.ClarinLicenseResourceUserAllowance; +import org.dspace.content.clarin.ClarinUserMetadata; +import org.dspace.content.clarin.ClarinUserRegistration; +import org.dspace.content.service.clarin.ClarinLicenseResourceUserAllowanceService; +import org.dspace.content.service.clarin.ClarinUserRegistrationService; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.eperson.service.EPersonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * Specialized controller created for Clarin-Dspace import user metadata. + * It creates ClarinLicenseResourceUserAllowance too. + * + * @author Michaela Paurikova (michaela.paurikova at dataquest.sk) + */ +@RestController +@RequestMapping("/api/clarin/import") +public class ClarinUserMetadataImportController { + private static final Logger log = org.apache.logging.log4j.LogManager + .getLogger(ClarinUserMetadataImportController.class); + + @Autowired + private EPersonService ePersonService; + @Autowired + private ClarinLicenseResourceUserAllowanceService clarinLicenseResourceUserAllowanceService; + @Autowired + private ClarinUserRegistrationService clarinUserRegistrationService; + @Autowired + private ConverterService converter; + @Autowired + private Utils utils; + @Autowired + private ClarinUserMetadataRestController clarinUserMetadataRestController; + + /** + * Endpoint for import user_metadata for eperson and bitstream. + * Endpoint creates ClarinLicenseResourceUserAllowance too, because we use the method in which it is doing. + * The mapping for requested endpoint, for example + *
+     * {@code
+     * https:///api/clarin/import/usermetadata
+     * }
+     * 
+ * @param request request + * @return created user metadata converted to rest object + */ + @PreAuthorize("hasAuthority('ADMIN')") + @RequestMapping(method = RequestMethod.POST, value = "/usermetadata") + public ClarinUserMetadataRest importUserMetadata(HttpServletRequest request) throws SQLException, IOException, + java.text.ParseException { + //controlling of the input parameters + Context context = obtainContext(request); + if (Objects.isNull(context)) { + throw new RuntimeException("Context is null!"); + } + + String userRegistrationIdString = request.getParameter("userRegistrationId"); + if (StringUtils.isBlank(userRegistrationIdString)) { + log.error("Required parameter userRegistrationId is null!"); + throw new RuntimeException("UserRegistrationId is null!"); + } + Integer userRegistrationId = Integer.parseInt(userRegistrationIdString); + + String bitstreamUUIDString = request.getParameter("bitstreamUUID"); + if (StringUtils.isBlank(bitstreamUUIDString)) { + log.error("Required parameter bitstreamUUID is null!"); + throw new RuntimeException("BitstreamUUID is null!"); + } + UUID bitstreamUUID = UUID.fromString(bitstreamUUIDString); + + log.info("Processing user registration id: " + userRegistrationId + " and bitstream UUID: " + bitstreamUUID); + + String createdOnString = request.getParameter("createdOn"); + if (StringUtils.isBlank(createdOnString)) { + log.error("Required parameter created_on is null!"); + throw new RuntimeException("Created_on is null!"); + } + Date createdOn = getDateFromString(createdOnString); + + //we don't control token, because it can be null + String token = request.getParameter("token"); + + ClarinUserRegistration userRegistration = clarinUserRegistrationService.find(context, + userRegistrationId); + if (Objects.isNull(userRegistration)) { + log.error("User registration with id: " + userRegistrationId + " doesn't exist!"); + throw new RuntimeException("User registration with id: " + userRegistrationId + " doesn't exist!"); + } + + //eperson can be null, we don't control, if it exists + EPerson ePerson = null; + if (Objects.nonNull(userRegistration.getPersonID())) { + ePerson = ePersonService.find(context, userRegistration.getPersonID()); + } + + // Get ClarinUserMetadataRest Array from the request body + ClarinUserMetadataRest[] clarinUserMetadataRestArray = + new ObjectMapper().readValue(request.getInputStream(), ClarinUserMetadataRest[].class); + if (ArrayUtils.isEmpty(clarinUserMetadataRestArray)) { + log.error("Cannot get clarinUserMetadataRestArray from request for user registration with id: " + + userRegistrationId + + " and bitstream with id: " + bitstreamUUID); + throw new RuntimeException("Cannot get clarinUserMetadataRestArray from request " + + "for user registration with id: " + + userRegistrationId + " and bitstream with id: " + bitstreamUUID); + } + // Convert Array to the List + List clarinUserMetadataRestList = Arrays.asList(clarinUserMetadataRestArray); + if (CollectionUtils.isEmpty(clarinUserMetadataRestList)) { + log.error("Cannot convert clarinUserMetadataRestArray to array for user registration with id: " + + userRegistrationId + + " and bitstream id: " + bitstreamUUID); + throw new RuntimeException("Cannot get clarinUserMetadataRestArray from " + + "request for user registration with id: " + + userRegistrationId + " and bitstream with id: " + bitstreamUUID); + } + + try { + // Get mapping between clarin license and the bitstream + ClarinLicenseResourceMapping clarinLicenseResourceMapping = + clarinUserMetadataRestController.getLicenseResourceMapping(context, bitstreamUUID); + if (Objects.isNull(clarinLicenseResourceMapping)) { + log.error("Cannot find the license resource mapping between clarin license" + + " and the bitstream with id: " + bitstreamUUID); + throw new NotFoundException("Cannot find the license resource mapping between clarin license" + + " and the bitstream with id: " + bitstreamUUID); + } + List newClarinUserMetadataList; + if (Objects.nonNull(ePerson)) { + // The user is signed in + //create user metadata and license resource user allowance + newClarinUserMetadataList = clarinUserMetadataRestController.processSignedInUser( + context, ePerson, clarinUserMetadataRestList, + clarinLicenseResourceMapping, bitstreamUUID, token); + } else { + // The user not is signed in + //create user metadata and license resource user allowance + newClarinUserMetadataList = clarinUserMetadataRestController.processNonSignedInUser( + context, clarinUserMetadataRestList, clarinLicenseResourceMapping, bitstreamUUID, token); + } + //set eperson_id (user registration) in user_metadata + newClarinUserMetadataList.get(0).setEperson(userRegistration); + //set created_on for created license_resource_user_allowance + //created list has to contain minimally one record + ClarinLicenseResourceUserAllowance clarinLicenseResourceUserAllowance = + newClarinUserMetadataList.get(0).getTransaction(); + clarinLicenseResourceUserAllowance.setCreatedOn(createdOn); + clarinLicenseResourceUserAllowanceService.update(context, clarinLicenseResourceUserAllowance); + //return created object as rest object + ClarinUserMetadataRest clarinUserMetadataRest = converter.toRest(newClarinUserMetadataList.get(0), + utils.obtainProjection()); + context.commit(); + + return clarinUserMetadataRest; + } catch (Exception e) { + log.error("Something is very very very wrong with user registration: " + userRegistration.getID() + + " and bitstream: " + + bitstreamUUID + ". Excemption: " + e.getMessage()); + throw new RuntimeException("Something is very very very wrong with user registration: " + + userRegistration.getID() + + " and bitstream: " + bitstreamUUID + ". Excemption: " + e.getMessage()); + } + } + + /** + * Convert String value to Date. + * Expects two possible date formats, but more can be added. + * @param value + * @return converted input value to Date + * @throws java.text.ParseException if parse error + */ + private Date getDateFromString(String value) throws java.text.ParseException { + Date output = null; + if (StringUtils.isBlank(value)) { + return null; + } + + SimpleDateFormat sdf; + sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS"); + try { + output = sdf.parse(value); + } catch (java.text.ParseException e) { + try { + sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSS"); + output = sdf.parse(value); + } catch (java.text.ParseException e1) { + sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS"); + output = sdf.parse(value); + } + } + return output; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinEPersonImportController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinEPersonImportController.java index 3eaadcffc791..ac5c31b211e6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinEPersonImportController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinEPersonImportController.java @@ -9,6 +9,7 @@ import static org.dspace.app.rest.utils.ContextUtil.obtainContext; +import java.io.IOException; import java.sql.SQLException; import java.text.DateFormat; import java.text.ParseException; @@ -16,10 +17,14 @@ import java.util.Date; import java.util.Objects; import java.util.UUID; +import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.converter.ConverterService; +import org.dspace.app.rest.exception.UnprocessableEntityException; +import org.dspace.app.rest.model.ClarinUserRegistrationRest; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.AuthorizeException; @@ -35,12 +40,12 @@ import org.springframework.web.bind.annotation.RestController; /** - * Specialized controller created for Clarin-Dspace eperson import. + * Specialized controller created for Clarin-Dspace eperson and user registration import. * * @author Michaela Paurikova (michaela.paurikova at dataquest.sk) */ @RestController -@RequestMapping("/api/clarin/import/" + EPersonRest.EPERSON) +@RequestMapping("/api/clarin/import") public class ClarinEPersonImportController { @Autowired private EPersonRestRepository ePersonRestRepository; @@ -54,7 +59,7 @@ public class ClarinEPersonImportController { private Utils utils; /** - * Endpoint for import eperson. Create user registration if it exists. + * Endpoint for import eperson. * The mapping for requested endpoint, for example *
      * {@code
@@ -67,7 +72,7 @@ public class ClarinEPersonImportController {
      * @throws SQLException       if database error
      */
     @PreAuthorize("hasAuthority('ADMIN')")
-    @RequestMapping(method = RequestMethod.POST)
+    @RequestMapping(method = RequestMethod.POST, value = "/eperson")
     public EPersonRest importEPerson(HttpServletRequest request)
             throws AuthorizeException, SQLException {
         Context context = obtainContext(request);
@@ -92,28 +97,55 @@ public EPersonRest importEPerson(HttpServletRequest request)
         eperson.setLastActive(lastActive);
         ePersonService.update(context, eperson);
 
-        String hasUserRegistrationString = request.getParameter("userRegistration");
-        boolean userRegistration = getBooleanFromString(hasUserRegistrationString);
-
-        //create user registration if exists
-        if (userRegistration) {
-            String organization = request.getParameter("organization");
-            String confirmationString = request.getParameter("confirmation");
-            boolean confirmation = getBooleanFromString(confirmationString);
-
-            ClarinUserRegistration clarinUserRegistration = new ClarinUserRegistration();
-            clarinUserRegistration.setOrganization(organization);
-            clarinUserRegistration.setConfirmation(confirmation);
-            clarinUserRegistration.setEmail(eperson.getEmail());
-            clarinUserRegistration.setPersonID(eperson.getID());
-            clarinUserRegistrationService.create(context, clarinUserRegistration);
-        }
         epersonRest = converter.toRest(eperson, utils.obtainProjection());
         context.complete();
 
         return epersonRest;
     }
 
+    /**
+     * Endpoint for import clarin user registration.
+     * The mapping for requested endpoint, for example
+     * 
+     * {@code
+     * https:///api/clarin/import/userregistration
+     * }
+     * 
+ * @param request request + * @return created clarin user registration converted to rest + * @throws AuthorizeException if authorization error + * @throws SQLException if database error + */ + @PreAuthorize("hasAuthority('ADMIN')") + @RequestMapping(method = RequestMethod.POST, value = "/userregistration") + public ClarinUserRegistrationRest importUserRegistration(HttpServletRequest request) + throws SQLException, AuthorizeException { + Context context = obtainContext(request); + if (Objects.isNull(context)) { + throw new RuntimeException("Context is null!"); + } + //get user registration from request + ObjectMapper mapper = new ObjectMapper(); + ClarinUserRegistrationRest userRegistrationRest = null; + try { + ServletInputStream input = request.getInputStream(); + userRegistrationRest = mapper.readValue(input, ClarinUserRegistrationRest.class); + } catch (IOException e1) { + throw new UnprocessableEntityException("Error parsing request body", e1); + } + //create user registration + ClarinUserRegistration clarinUserRegistration = new ClarinUserRegistration(); + clarinUserRegistration.setOrganization(userRegistrationRest.getOrganization()); + clarinUserRegistration.setConfirmation(userRegistrationRest.isConfirmation()); + clarinUserRegistration.setEmail(userRegistrationRest.getEmail()); + clarinUserRegistration.setPersonID(userRegistrationRest.getePersonID()); + clarinUserRegistration = clarinUserRegistrationService.create(context, clarinUserRegistration); + userRegistrationRest = converter.toRest(clarinUserRegistration, utils.obtainProjection()); + context.commit(); + return userRegistrationRest; + } + + /** * Convert String value to boolean. * @param value input value diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java index 1bac66f5e919..b449954dfe48 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java @@ -204,7 +204,7 @@ private String getEmailFromUserMetadata(List clarinUserM return email; } - public void processSignedInUser(Context context, EPerson currentUser, + public List processSignedInUser(Context context, EPerson currentUser, List clarinUserMetadataRestList, ClarinLicenseResourceMapping clarinLicenseResourceMapping, UUID bitstreamUUID, String downloadToken) @@ -275,6 +275,7 @@ public void processSignedInUser(Context context, EPerson currentUser, clarinUserMetadata.setTransaction(clrua); clarinUserMetadataService.update(context, clarinUserMetadata); } + return newClarinUserMetadataList; } private ClarinLicenseResourceUserAllowance createClrua(Context context, @@ -298,7 +299,7 @@ private ClarinLicenseResourceUserAllowance createClrua(Context context, return clrua; } - private void processNonSignedInUser(Context context, + public List processNonSignedInUser(Context context, List clarinUserMetadataRestList, ClarinLicenseResourceMapping clarinLicenseResourceMapping, UUID bitstreamUUID, @@ -309,14 +310,21 @@ private void processNonSignedInUser(Context context, clarinUserMetadataRestList); // Create ClarinResourceUserAllowance record to generate token. - this.createClrua(context, clarinLicenseResourceMapping, clarinUserMetadataList, downloadToken, null); + ClarinLicenseResourceUserAllowance clrua = this.createClrua(context, clarinLicenseResourceMapping, + clarinUserMetadataList, downloadToken, null); + // Add Clarin License Resource Allowance to the user metadata records + for (ClarinUserMetadata clarinUserMetadata : clarinUserMetadataList) { + clarinUserMetadata.setTransaction(clrua); + clarinUserMetadataService.update(context, clarinUserMetadata); + } + return clarinUserMetadataList; } private String generateToken() { return UUID.randomUUID().toString(); } - private ClarinLicenseResourceMapping getLicenseResourceMapping(Context context, UUID bitstreamUUID) + public ClarinLicenseResourceMapping getLicenseResourceMapping(Context context, UUID bitstreamUUID) throws SQLException { // Get ClarinLicense to check if it needs to generate the token List clarinLicenseResourceMappingList = diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinEPersonImportControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinEPersonImportControllerIT.java index aaa8183d9de3..520e0d4726b4 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinEPersonImportControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinEPersonImportControllerIT.java @@ -18,11 +18,11 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.databind.ObjectMapper; +import org.dspace.app.rest.model.ClarinUserRegistrationRest; import org.dspace.app.rest.model.EPersonRest; import org.dspace.app.rest.model.MetadataRest; import org.dspace.app.rest.model.MetadataValueRest; @@ -37,7 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired; /** - * Integration test to test the /api/clarin/import/eperson/* endpoints + * Integration test to test the /api/clarin/import/* endpoints * * @author Michaela Paurikova (michaela.paurikova at dataquest.sk) */ @@ -50,7 +50,7 @@ public class ClarinEPersonImportControllerIT extends AbstractControllerIntegrat private ClarinUserRegistrationService clarinUserRegistrationService; @Test - public void createEpersonWithUserRegistrationTest() throws Exception { + public void createEpersonTest() throws Exception { ObjectMapper mapper = new ObjectMapper(); EPersonRest data = new EPersonRest(); MetadataRest metadataRest = new MetadataRest(); @@ -74,10 +74,7 @@ public void createEpersonWithUserRegistrationTest() throws Exception { .contentType(contentType) .param("projection", "full") .param("selfRegistered", "true") - .param("lastActive", "2018-02-10T13:21:29.733") - .param("userRegistration", "true") - .param("organization", "https://test.com") - .param("confirmation", "false")) + .param("lastActive", "2018-02-10T13:21:29.733")) .andExpect(status().isOk()) .andDo(result -> idRef .set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id")))); @@ -92,23 +89,13 @@ public void createEpersonWithUserRegistrationTest() throws Exception { assertEquals(createdEperson.getFirstName(), "John"); assertEquals(createdEperson.getLastName(), "Doe"); - //control the creation of the user registration - List userRegistrations = clarinUserRegistrationService.findByEPersonUUID( - context, idRef.get()); - assertEquals(userRegistrations.size(), 1); - ClarinUserRegistration userRegistration = userRegistrations.get(0); - assertEquals(userRegistration.getEmail(), "createtest@example.com"); - assertEquals(userRegistration.getOrganization(), "https://test.com"); - assertFalse(userRegistration.isConfirmation()); - //clean all - ClarinUserRegistrationBuilder.deleteClarinUserRegistration(userRegistration.getID()); } finally { EPersonBuilder.deleteEPerson(idRef.get()); } } @Test - public void createEpersonWithoutUserRegistrationTest() throws Exception { + public void createEpersonDifferentLastActiveFormatTest() throws Exception { ObjectMapper mapper = new ObjectMapper(); EPersonRest data = new EPersonRest(); MetadataRest metadataRest = new MetadataRest(); @@ -132,80 +119,60 @@ public void createEpersonWithoutUserRegistrationTest() throws Exception { .contentType(contentType) .param("projection", "full") .param("selfRegistered", "true") - .param("lastActive", "2018-02-10T13:21:29.733") - .param("userRegistration", "false")) + .param("lastActive", "2018-02-10T13:21:29.733")) .andExpect(status().isOk()) .andDo(result -> idRef .set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id")))); EPerson createdEperson = ePersonService.find(context, idRef.get()); + assertEquals(getStringFromDate(createdEperson.getLastActive()), "2018-02-10T13:21:29.733"); assertTrue(createdEperson.getSelfRegistered()); + assertEquals(createdEperson.getEmail(),"createtest@example.com"); + assertTrue(createdEperson.canLogIn()); + assertFalse(createdEperson.getRequireCertificate()); + assertEquals(createdEperson.getFirstName(), "John"); + assertEquals(createdEperson.getLastName(), "Doe"); - //control the creation of the user registration - List userRegistrations = clarinUserRegistrationService.findByEPersonUUID(context, - idRef.get()); - assertEquals(userRegistrations.size(), 0); } finally { EPersonBuilder.deleteEPerson(idRef.get()); } } @Test - public void createEpersonWithUserRegistrationDifferentLastActiveFormatTest() throws Exception { + public void createUserRegistrationTest() throws Exception { ObjectMapper mapper = new ObjectMapper(); - EPersonRest data = new EPersonRest(); - MetadataRest metadataRest = new MetadataRest(); - data.setEmail("createtest@example.com"); - data.setCanLogIn(true); - MetadataValueRest surname = new MetadataValueRest(); - surname.setValue("Doe"); - metadataRest.put("eperson.lastname", surname); - MetadataValueRest firstname = new MetadataValueRest(); - firstname.setValue("John"); - metadataRest.put("eperson.firstname", firstname); - data.setMetadata(metadataRest); - - AtomicReference idRef = new AtomicReference(); + context.turnOffAuthorisationSystem(); + EPerson ePerson = EPersonBuilder.createEPerson(context) + .withEmail("eperson3@mail.com") + .withPassword("qwerty03") + .build(); + context.restoreAuthSystemState(); + ClarinUserRegistrationRest userRegistrationRest = new ClarinUserRegistrationRest(); + userRegistrationRest.setConfirmation(true); + userRegistrationRest.setEmail("test@test.edu"); + userRegistrationRest.setePersonID(ePerson.getID()); + userRegistrationRest.setOrganization("Test"); + + AtomicReference idRef = new AtomicReference(); String authToken = getAuthToken(admin.getEmail(), password); try { - getClient(authToken).perform(post("/api/clarin/import/eperson") - .content(mapper.writeValueAsBytes(data)) - .contentType(contentType) - .param("projection", "full") - .param("selfRegistered", "true") - .param("lastActive", "2018-02-10T13:21:29.733") - .param("userRegistration", "true") - .param("organization", "https://test.com") - .param("confirmation", "false")) + getClient(authToken).perform(post("/api/clarin/import/userregistration") + .content(mapper.writeValueAsBytes(userRegistrationRest)) + .contentType(contentType)) .andExpect(status().isOk()) .andDo(result -> idRef - .set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id")))); - - EPerson createdEperson = ePersonService.find(context, idRef.get()); - - assertEquals(getStringFromDate(createdEperson.getLastActive()), "2018-02-10T13:21:29.733"); - assertTrue(createdEperson.getSelfRegistered()); - assertEquals(createdEperson.getEmail(),"createtest@example.com"); - assertTrue(createdEperson.canLogIn()); - assertFalse(createdEperson.getRequireCertificate()); - assertEquals(createdEperson.getFirstName(), "John"); - assertEquals(createdEperson.getLastName(), "Doe"); - - //control the creation of the user registration - List userRegistrations = clarinUserRegistrationService.findByEPersonUUID(context, - idRef.get()); - assertEquals(userRegistrations.size(), 1); - ClarinUserRegistration userRegistration = userRegistrations.get(0); - assertEquals(userRegistration.getEmail(), "createtest@example.com"); - assertEquals(userRegistration.getOrganization(), "https://test.com"); - assertFalse(userRegistration.isConfirmation()); - //clean all - ClarinUserRegistrationBuilder.deleteClarinUserRegistration(userRegistration.getID()); + .set(read(result.getResponse().getContentAsString(), "$.id"))); + //control + ClarinUserRegistration clarinUserRegistration = clarinUserRegistrationService.find(context, idRef.get()); + assertTrue(clarinUserRegistration.isConfirmation()); + assertEquals(clarinUserRegistration.getEmail(), "test@test.edu"); + assertEquals(clarinUserRegistration.getPersonID(), ePerson.getID()); + assertEquals(clarinUserRegistration.getOrganization(), "Test"); } finally { - EPersonBuilder.deleteEPerson(idRef.get()); + ClarinUserRegistrationBuilder.deleteClarinUserRegistration(idRef.get()); } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinUserMetadataImportControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinUserMetadataImportControllerIT.java new file mode 100644 index 000000000000..1db39d2b8d81 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinUserMetadataImportControllerIT.java @@ -0,0 +1,294 @@ +/** + * 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.dspace.app.rest.repository.ClarinLicenseRestRepository.OPERATION_PATH_LICENSE_RESOURCE; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.InputStream; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.rest.model.ClarinUserMetadataRest; +import org.dspace.app.rest.model.patch.Operation; +import org.dspace.app.rest.model.patch.ReplaceOperation; +import org.dspace.app.rest.test.AbstractEntityIntegrationTest; +import org.dspace.authorize.AuthorizeException; +import org.dspace.builder.ClarinLicenseBuilder; +import org.dspace.builder.ClarinLicenseLabelBuilder; +import org.dspace.builder.ClarinUserMetadataBuilder; +import org.dspace.builder.ClarinUserRegistrationBuilder; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.WorkspaceItemBuilder; +import org.dspace.content.Bitstream; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.clarin.ClarinLicense; +import org.dspace.content.clarin.ClarinLicenseLabel; +import org.dspace.content.clarin.ClarinUserMetadata; +import org.dspace.content.clarin.ClarinUserRegistration; +import org.dspace.content.service.clarin.ClarinLicenseLabelService; +import org.dspace.content.service.clarin.ClarinLicenseService; +import org.dspace.content.service.clarin.ClarinUserMetadataService; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; + +/** + * Integration test to test the /api/clarin/import/* endpoints + * + * @author Michaela Paurikova (michaela.paurikova at dataquest.sk) + */ +public class ClarinUserMetadataImportControllerIT extends AbstractEntityIntegrationTest { + + @Autowired + ClarinLicenseService clarinLicenseService; + @Autowired + ClarinLicenseLabelService clarinLicenseLabelService; + @Autowired + ClarinUserMetadataService clarinUserMetadataService; + + WorkspaceItem witem; + ClarinLicense clarinLicense; + Bitstream bitstream; + + // Attach ClarinLicense to the Bitstream + private void prepareEnvironment(String requiredInfo) throws Exception { + // 1. Create Workspace Item with uploaded file + // 2. Create Clarin License + // 3. Send request to add Clarin License to the Workspace Item + // 4. Check if the Clarin License name was added to the Item's metadata `dc.rights` + // 5. Check if the Clarin License was attached to the Bitstream + + // 1. Create WI with uploaded file + context.turnOffAuthorisationSystem(); + witem = createWorkspaceItemWithFile(); + + List replaceOperations = new ArrayList(); + String clarinLicenseName = "Test Clarin License"; + + // 2. Create clarin license with clarin license label + clarinLicense = createClarinLicense(clarinLicenseName, "Test Def", requiredInfo, 0); + + // creating replace operation + Map licenseReplaceOpValue = new HashMap(); + licenseReplaceOpValue.put("value", clarinLicenseName); + replaceOperations.add(new ReplaceOperation("/" + OPERATION_PATH_LICENSE_RESOURCE, + licenseReplaceOpValue)); + + context.restoreAuthSystemState(); + String updateBody = getPatchContent(replaceOperations); + + // 3. Send request to add Clarin License to the Workspace Item + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(patch("/api/submission/workspaceitems/" + witem.getID()) + .content(updateBody) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + // 4. Check if the Clarin License name was added to the Item's metadata `dc.rights` + getClient(tokenAdmin).perform(get("/api/submission/workspaceitems/" + witem.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.item.metadata['dc.rights'][0].value", is(clarinLicenseName))); + + // 5. Check if the Clarin License was attached to the Bitstream + getClient(tokenAdmin).perform(get("/api/core/clarinlicenses/" + clarinLicense.getID())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.bitstreams", is(1))); + } + + @Test + public void importUserMetadataWithEpersonTest() throws Exception { + this.prepareEnvironment("NAME"); + context.turnOffAuthorisationSystem(); + ClarinUserRegistration clarinUserRegistration = ClarinUserRegistrationBuilder + .createClarinUserRegistration(context).withEPersonID(admin.getID()).build(); + context.restoreAuthSystemState(); + ObjectMapper mapper = new ObjectMapper(); + ClarinUserMetadataRest clarinUserMetadata1 = new ClarinUserMetadataRest(); + clarinUserMetadata1.setMetadataKey("NAME"); + clarinUserMetadata1.setMetadataValue("Test"); + + List clarinUserMetadataRestList = new ArrayList<>(); + clarinUserMetadataRestList.add(clarinUserMetadata1); + + String adminToken = getAuthToken(admin.getEmail(), password); + + // There should exist record in the UserRegistration table + getClient(adminToken).perform(get("/api/core/clarinuserregistrations") + .contentType(contentType)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.totalElements", is(1))); + + // Manage UserMetadata and get token + getClient(adminToken).perform(post("/api/clarin/import/usermetadata") + .content(mapper.writeValueAsBytes(clarinUserMetadataRestList.toArray())) + .contentType(MediaType.APPLICATION_JSON) + .param("userRegistrationId", clarinUserRegistration.getID().toString()) + .param("bitstreamUUID", bitstream.getID().toString()) + .param("createdOn", "2012-09-19T10:30:03.741633") + .param("token", "111")) + .andExpect(status().isOk()); + + //find created data and control it + ClarinUserMetadata clarinUserMetadata = clarinUserMetadataService.findAll(context).get(0); + assertEquals(clarinUserMetadata.getMetadataKey(), "NAME"); + assertEquals(clarinUserMetadata.getMetadataValue(), "Test"); + assertEquals(clarinUserMetadata.getEperson().getPersonID(), admin.getID()); + assertEquals(clarinUserMetadata.getTransaction().getCreatedOn().getTime(), + getDateFromString("2012-09-19T10:30:03.741633").getTime()); + assertEquals(clarinUserMetadata.getTransaction().getToken(), "111"); + + //clean all + ClarinUserMetadataBuilder.deleteClarinUserMetadata(clarinUserRegistration.getID()); + } + + @Test + public void importUserMetadataWithoutEpersonTest() throws Exception { + this.prepareEnvironment("NAME"); + context.turnOffAuthorisationSystem(); + ClarinUserRegistration clarinUserRegistration = ClarinUserRegistrationBuilder + .createClarinUserRegistration(context).withEPersonID(admin.getID()).build(); + clarinUserRegistration.setPersonID(null); + context.restoreAuthSystemState(); + ObjectMapper mapper = new ObjectMapper(); + ClarinUserMetadataRest clarinUserMetadata1 = new ClarinUserMetadataRest(); + clarinUserMetadata1.setMetadataKey("NAME"); + clarinUserMetadata1.setMetadataValue("Test"); + + List clarinUserMetadataRestList = new ArrayList<>(); + clarinUserMetadataRestList.add(clarinUserMetadata1); + + String adminToken = getAuthToken(admin.getEmail(), password); + + // There should exist record in the UserRegistration table + getClient(adminToken).perform(get("/api/core/clarinuserregistrations") + .contentType(contentType)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.totalElements", is(1))); + + // Manage UserMetadata and get token + getClient(adminToken).perform(post("/api/clarin/import/usermetadata") + .content(mapper.writeValueAsBytes(clarinUserMetadataRestList.toArray())) + .contentType(MediaType.APPLICATION_JSON) + .param("userRegistrationId", clarinUserRegistration.getID().toString()) + .param("bitstreamUUID", bitstream.getID().toString()) + .param("createdOn", "2012-09-19T10:30:03.741633") + .param("token", "111")) + .andExpect(status().isOk()); + + //find created data and control it + ClarinUserMetadata clarinUserMetadata = clarinUserMetadataService.findAll(context).get(0); + assertEquals(clarinUserMetadata.getMetadataKey(), "NAME"); + assertEquals(clarinUserMetadata.getMetadataValue(), "Test"); + assertEquals(clarinUserMetadata.getEperson().getPersonID(), null); + assertEquals(clarinUserMetadata.getTransaction().getCreatedOn().getTime(), + getDateFromString("2012-09-19T10:30:03.741633").getTime()); + assertEquals(clarinUserMetadata.getTransaction().getToken(), "111"); + + //clean all + ClarinUserMetadataBuilder.deleteClarinUserMetadata(clarinUserRegistration.getID()); + } + + /** + * Create Workspace item with file. + */ + private WorkspaceItem createWorkspaceItemWithFile() { + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1) + .withName("Collection 1") + .build(); + + context.setCurrentUser(eperson); + InputStream pdf = getClass().getResourceAsStream("simple-article.pdf"); + + WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withTitle("Test WorkspaceItem") + .withIssueDate("2017-10-17") + .withFulltext("simple-article.pdf", "/local/path/simple-article.pdf", pdf) + .build(); + + bitstream = witem.getItem().getBundles().get(0).getBitstreams().get(0); + + return witem; + } + + /** + * Create Clarin License Label object for testing purposes. + */ + private ClarinLicenseLabel createClarinLicenseLabel(String label, boolean extended, String title) + throws SQLException, AuthorizeException { + ClarinLicenseLabel clarinLicenseLabel = ClarinLicenseLabelBuilder.createClarinLicenseLabel(context).build(); + clarinLicenseLabel.setLabel(label); + clarinLicenseLabel.setExtended(extended); + clarinLicenseLabel.setTitle(title); + + clarinLicenseLabelService.update(context, clarinLicenseLabel); + return clarinLicenseLabel; + } + + /** + * Create ClarinLicense object with ClarinLicenseLabel object for testing purposes. + */ + private ClarinLicense createClarinLicense(String name, String definition, String requiredInfo, int confirmation) + throws SQLException, AuthorizeException { + ClarinLicense clarinLicense = ClarinLicenseBuilder.createClarinLicense(context).build(); + clarinLicense.setConfirmation(confirmation); + clarinLicense.setDefinition(definition); + clarinLicense.setRequiredInfo(requiredInfo); + clarinLicense.setName(name); + + // Add ClarinLicenseLabels to the ClarinLicense + HashSet clarinLicenseLabels = new HashSet<>(); + ClarinLicenseLabel clarinLicenseLabel = createClarinLicenseLabel("lbl", false, "Test Title"); + clarinLicenseLabels.add(clarinLicenseLabel); + clarinLicense.setLicenseLabels(clarinLicenseLabels); + + clarinLicenseService.update(context, clarinLicense); + return clarinLicense; + } + + /** + * Convert String date to Date. + */ + private Date getDateFromString(String value) throws java.text.ParseException { + Date output = null; + if (StringUtils.isBlank(value)) { + return null; + } + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS"); + try { + output = sdf.parse(value); + } catch (java.text.ParseException e) { + throw new RuntimeException("Cannot convert date: " + value + " from String to Date."); + } + return output; + } +}