From 22d2bd31ed91d611aefe669f261dd56731a6f28d Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Mon, 2 Sep 2024 16:19:38 +0100 Subject: [PATCH 01/36] Added unique constraint for external id identifier for disambiguated org (#7074) Co-authored-by: Angel Montenegro --- orcid-persistence/src/main/resources/db-master.xml | 1 + ...que_constraint_external_id_disambiguated_org.xml | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 orcid-persistence/src/main/resources/db/updates/add_unique_constraint_external_id_disambiguated_org.xml diff --git a/orcid-persistence/src/main/resources/db-master.xml b/orcid-persistence/src/main/resources/db-master.xml index 3f0df9ca962..c1a531b9bb3 100644 --- a/orcid-persistence/src/main/resources/db-master.xml +++ b/orcid-persistence/src/main/resources/db-master.xml @@ -403,4 +403,5 @@ + \ No newline at end of file diff --git a/orcid-persistence/src/main/resources/db/updates/add_unique_constraint_external_id_disambiguated_org.xml b/orcid-persistence/src/main/resources/db/updates/add_unique_constraint_external_id_disambiguated_org.xml new file mode 100644 index 00000000000..50781875b77 --- /dev/null +++ b/orcid-persistence/src/main/resources/db/updates/add_unique_constraint_external_id_disambiguated_org.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file From b0d6c11401cd460c907c8ed914bfbd27395e8145 Mon Sep 17 00:00:00 2001 From: github actions Date: Mon, 2 Sep 2024 15:33:31 +0000 Subject: [PATCH 02/36] v2.64.3 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d888754cba..50b3880afd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.64.3 - 2024-09-02 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.2...v2.64.3) + ## v2.64.2 - 2024-08-28 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.1...v2.64.2) From 6d862d3e6b8cfd873b7c0012e48576b0e18ba4e3 Mon Sep 17 00:00:00 2001 From: leomendoza123 Date: Tue, 3 Sep 2024 14:15:45 -0600 Subject: [PATCH 03/36] Lmendoza/new relic browser monitoring (#7081) * tx pull tr * tx pull pt * tx pull * manual revert * new-relic-browser-monitoring --------- Co-authored-by: Leonardo Mendoza Fernadez --- orcid-core/src/main/java/org/orcid/core/togglz/Features.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/orcid-core/src/main/java/org/orcid/core/togglz/Features.java b/orcid-core/src/main/java/org/orcid/core/togglz/Features.java index 0151c946ae3..643e86e665f 100644 --- a/orcid-core/src/main/java/org/orcid/core/togglz/Features.java +++ b/orcid-core/src/main/java/org/orcid/core/togglz/Features.java @@ -7,6 +7,9 @@ public enum Features implements Feature { + @Label("New Relic Browser Monitoring") + NEW_RELIC_BROWSER_MONITORING, + @Label("Public record header with summary") NEW_RECORD_HEADER_WITH_SUMMARY, From 0217b47874bf28e71dc422462cdd19bcfa54bcca Mon Sep 17 00:00:00 2001 From: github actions Date: Tue, 3 Sep 2024 20:30:40 +0000 Subject: [PATCH 04/36] v2.64.4 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b3880afd6..2bf6d557182 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.64.4 - 2024-09-03 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.3...v2.64.4) + ## v2.64.3 - 2024-09-02 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.2...v2.64.3) From 4a2ddda00247ee2444c71dd6d3291aba02439da6 Mon Sep 17 00:00:00 2001 From: andrej romanov <50377758+auumgn@users.noreply.github.com> Date: Wed, 4 Sep 2024 15:12:57 +0300 Subject: [PATCH 05/36] Remove old togglz (#7080) * remove old togglz * remove REGISTRATION_2_0 togglz checks --- .../java/org/orcid/core/togglz/Features.java | 17 +---------------- .../web/controllers/RegistrationController.java | 4 ++-- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/orcid-core/src/main/java/org/orcid/core/togglz/Features.java b/orcid-core/src/main/java/org/orcid/core/togglz/Features.java index 643e86e665f..389a28d2dc9 100644 --- a/orcid-core/src/main/java/org/orcid/core/togglz/Features.java +++ b/orcid-core/src/main/java/org/orcid/core/togglz/Features.java @@ -9,28 +9,13 @@ public enum Features implements Feature { @Label("New Relic Browser Monitoring") NEW_RELIC_BROWSER_MONITORING, - - @Label("Public record header with summary") - NEW_RECORD_HEADER_WITH_SUMMARY, - - @Label("Sign in updates V1") - SIGN_IN_UPDATES_V1, - + @Label("Homepage Headless WordPress") WORDPRESS_HOME_PAGE, - @Label("Registration 2.1: Add affiliations on registration") - REGISTRATION_2_1, - - @Label("Registration 2.0") - REGISTRATION_2_0, - @Label("Track user events") EVENTS, - @Label("Professional activities") - PROFESSIONAL_ACTIVITIES, - @Label("Redirect PUT token actions from *.pub.orcid.org to *.orcid.org") REDIRECT_PUT_TOKEN_ENDPOINT, diff --git a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java index d74d99c4ec8..e6af77a3415 100644 --- a/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java +++ b/orcid-web/src/main/java/org/orcid/frontend/web/controllers/RegistrationController.java @@ -328,7 +328,7 @@ public void validateRegistrationFields(HttpServletRequest request, Registration regEmailValidate(request, reg, false, false); registerTermsOfUseValidate(reg); - if (Features.REGISTRATION_2_0.isActive() && reg.getAffiliationForm() != null) { + if (reg.getAffiliationForm() != null) { AffiliationForm affiliationForm = reg.getAffiliationForm(); if (!AffiliationType.EMPLOYMENT.equals(AffiliationType.fromValue(affiliationForm.getAffiliationType().getValue()))) { setError(affiliationForm.getAffiliationType(), "Invalid affiliation type"); @@ -551,7 +551,7 @@ private void createMinimalRegistrationAndLogUserIn(HttpServletRequest request, H String unencryptedPassword = registration.getPassword().getValue(); String orcidId = createMinimalRegistration(request, registration, usedCaptchaVerification, locale, ip); logUserIn(request, response, orcidId, unencryptedPassword); - if (Features.REGISTRATION_2_0.isActive() && registration.getAffiliationForm() != null) { + if (registration.getAffiliationForm() != null) { createAffiliation(registration, orcidId); } } From 1da041fb3e704dda3a9a304df37987ee4a7d40d6 Mon Sep 17 00:00:00 2001 From: github actions Date: Wed, 4 Sep 2024 12:28:25 +0000 Subject: [PATCH 06/36] v2.64.5 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf6d557182..7b3b9e6ff51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.64.5 - 2024-09-04 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.4...v2.64.5) + ## v2.64.4 - 2024-09-03 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.3...v2.64.4) From d9819e2cb8f89ee64d57f7eab119268461d33113 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:23:50 +0100 Subject: [PATCH 07/36] Added extra logging for exceptions when indexing orgs (#7082) --- .../core/manager/impl/OrgDisambiguatedManagerImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java index 0ea7b06e63e..3a47eb28b31 100644 --- a/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java @@ -91,7 +91,12 @@ synchronized public void processOrgsForIndexing() { entities = orgDisambiguatedDaoReadOnly.findOrgsPendingIndexing(startIndex, indexingBatchSize); LOGGER.info("Found chunk of {} disambiguated orgs for indexing", entities.size()); for (OrgDisambiguatedEntity entity : entities) { - processDisambiguatedOrgInTransaction(entity); + try { + processDisambiguatedOrgInTransaction(entity); + } + catch(Exception ex) { + LOGGER.error("@@@FAILED to process the disambiguated org" + entity.getId() + " source id: " + entity.getSourceId(), ex); + } } startIndex = startIndex + indexingBatchSize; } while (!entities.isEmpty()); From 76920bbcce1b1375111f4e61496d1a7081fd04e8 Mon Sep 17 00:00:00 2001 From: github actions Date: Fri, 6 Sep 2024 16:01:27 +0000 Subject: [PATCH 08/36] v2.64.6 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b3b9e6ff51..1535aa905a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.64.6 - 2024-09-06 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.5...v2.64.6) + ## v2.64.5 - 2024-09-04 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.4...v2.64.5) From 2f3f59cb39f445dad3538e25256ed33ee562d01a Mon Sep 17 00:00:00 2001 From: github actions Date: Fri, 13 Sep 2024 19:07:27 +0000 Subject: [PATCH 09/36] v2.65.0 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1535aa905a4..676a7bc6c21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.65.0 - 2024-09-13 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.6...v2.65.0) + ## v2.64.6 - 2024-09-06 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.5...v2.64.6) From 2bdc44993ae6382e996da99ae90d847071327490 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:14:36 +0100 Subject: [PATCH 10/36] First draft education, qualifications, research resources, email domains added to record summary (#7084) * First draft education, qualification and research resources added to record summary * Added the implementation for emailDomains * Email domain fixes + fix for failing tests * Fixed the failing test by specifying the right xml order * Added the new summaries to the record marshalling test * Added the updated orcid-model version and fixed the last modified element --- .../manager/impl/SummaryManagerImpl.java | 285 ++++++++++++++---- .../core/model/EducationQualification.java | 119 ++++++++ .../core/model/EducationQualifications.java | 62 ++++ .../org/orcid/core/model/EmailDomain.java | 68 +++++ .../org/orcid/core/model/EmailDomains.java | 62 ++++ .../org/orcid/core/model/RecordSummary.java | 41 ++- .../orcid/core/model/ResearchResources.java | 18 ++ .../pojo/summary/EmailDomainSummary.java | 56 ++++ .../orcid/pojo/summary/RecordSummaryPojo.java | 56 ++++ .../common/manager/SummaryManagerTest.java | 40 +++ .../model/RecordSummaryMarshallingTest.java | 53 +++- .../org/orcid/core/model/summary-3.0.xml | 2 +- pom.xml | 2 +- 13 files changed, 792 insertions(+), 72 deletions(-) create mode 100644 orcid-core/src/main/java/org/orcid/core/model/EducationQualification.java create mode 100644 orcid-core/src/main/java/org/orcid/core/model/EducationQualifications.java create mode 100644 orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java create mode 100644 orcid-core/src/main/java/org/orcid/core/model/EmailDomains.java create mode 100644 orcid-core/src/main/java/org/orcid/core/model/ResearchResources.java create mode 100644 orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java diff --git a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java index 190e19d01e5..766f3f4f65a 100644 --- a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java @@ -18,10 +18,16 @@ import org.orcid.core.manager.v3.read_only.AffiliationsManagerReadOnly; import org.orcid.core.manager.v3.read_only.ExternalIdentifierManagerReadOnly; import org.orcid.core.manager.v3.read_only.PeerReviewManagerReadOnly; +import org.orcid.core.manager.v3.read_only.ProfileEmailDomainManagerReadOnly; import org.orcid.core.manager.v3.read_only.ProfileFundingManagerReadOnly; import org.orcid.core.manager.v3.read_only.RecordManagerReadOnly; import org.orcid.core.manager.v3.read_only.RecordNameManagerReadOnly; import org.orcid.core.manager.v3.read_only.WorkManagerReadOnly; +import org.orcid.core.manager.v3.read_only.ResearchResourceManagerReadOnly; +import org.orcid.core.model.EducationQualification; +import org.orcid.core.model.EducationQualifications; +import org.orcid.core.model.EmailDomain; +import org.orcid.core.model.EmailDomains; import org.orcid.core.model.Employment; import org.orcid.core.model.Employments; import org.orcid.core.model.ExternalIdentifier; @@ -31,7 +37,9 @@ import org.orcid.core.model.ProfessionalActivities; import org.orcid.core.model.ProfessionalActivity; import org.orcid.core.model.RecordSummary; +import org.orcid.core.model.ResearchResources; import org.orcid.core.model.Works; +import org.orcid.core.togglz.Features; import org.orcid.core.utils.JsonUtils; import org.orcid.core.utils.cache.redis.RedisClient; import org.orcid.core.utils.v3.SourceUtils; @@ -49,14 +57,19 @@ import org.orcid.jaxb.model.v3.release.record.SourceAware; import org.orcid.jaxb.model.v3.release.record.summary.AffiliationGroup; import org.orcid.jaxb.model.v3.release.record.summary.DistinctionSummary; +import org.orcid.jaxb.model.v3.release.record.summary.EducationSummary; import org.orcid.jaxb.model.v3.release.record.summary.InvitedPositionSummary; import org.orcid.jaxb.model.v3.release.record.summary.MembershipSummary; +import org.orcid.jaxb.model.v3.release.record.summary.QualificationSummary; import org.orcid.jaxb.model.v3.release.record.summary.ServiceSummary; import org.orcid.jaxb.model.v3.release.record.summary.WorkGroup; import org.orcid.jaxb.model.v3.release.record.summary.WorkSummary; +import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity; import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.pojo.PeerReviewMinimizedSummary; +import org.orcid.pojo.ajaxForm.Date; import org.orcid.pojo.summary.AffiliationSummary; +import org.orcid.pojo.summary.EmailDomainSummary; import org.orcid.pojo.summary.ExternalIdentifiersSummary; import org.orcid.pojo.summary.RecordSummaryPojo; import org.orcid.utils.DateUtils; @@ -85,33 +98,39 @@ public class SummaryManagerImpl implements SummaryManager { @Resource(name = "recordManagerReadOnlyV3") private RecordManagerReadOnly recordManagerReadOnly; + @Resource(name = "researchResourceManagerReadOnlyV3") + private ResearchResourceManagerReadOnly researchResourceManagerReadOnly; + + @Resource(name = "profileEmailDomainManagerReadOnly") + private ProfileEmailDomainManagerReadOnly profileEmailDomainManagerReadOnly; + @Resource private ProfileEntityCacheManager profileEntityCacheManager; @Resource private WorksCacheManager worksCacheManager; - + @Resource - private RedisClient redisClient; - - @Value("${org.orcid.core.utils.cache.redis.summary.enabled:false}") + private RedisClient redisClient; + + @Value("${org.orcid.core.utils.cache.redis.summary.enabled:false}") private boolean isSummaryCacheEnabled; - + // Set the cache TTL for the summary, 1 day by default - @Value("${org.orcid.core.utils.cache.redis.summary.ttl:3600}") + @Value("${org.orcid.core.utils.cache.redis.summary.ttl:3600}") private int summaryCacheTTL; @Override public RecordSummary getRecordSummary(String orcid) { String cacheKey = getCacheKey(orcid); // Check the cache - if(isSummaryCacheEnabled) { + if (isSummaryCacheEnabled) { String summaryString = redisClient.get(cacheKey); - if(StringUtils.isNotBlank(summaryString)) { - return JsonUtils.readObjectFromJsonString(summaryString, RecordSummary.class); + if (StringUtils.isNotBlank(summaryString)) { + return JsonUtils.readObjectFromJsonString(summaryString, RecordSummary.class); } } - + RecordSummary recordSummary = new RecordSummary(); // Set ORCID identifier @@ -137,12 +156,18 @@ public RecordSummary getRecordSummary(String orcid) { generateFundingSummary(recordSummary, orcid); // Generate the peer review summary - generatePeerReviewSummary(recordSummary, orcid); - + generatePeerReviewSummary(recordSummary, orcid); + + // Generate the research resources summary + generateResearchResourcesSummary(recordSummary, orcid); + + // generate email domains summary + generateEmailDomainsSummary(recordSummary, orcid); + // Set the summary in the cache - if(isSummaryCacheEnabled) { + if (isSummaryCacheEnabled) { redisClient.set(cacheKey, JsonUtils.convertToJsonString(recordSummary), summaryCacheTTL); - } + } return recordSummary; } @@ -151,21 +176,21 @@ public RecordSummaryPojo getRecordSummaryPojo(String orcid) { RecordSummary recordSummary = getRecordSummary(orcid); RecordSummaryPojo pojo = new RecordSummaryPojo(); pojo.setStatus("active"); - + pojo.setOrcid(recordSummary.getOrcidIdentifier().getUri()); - pojo.setName(recordSummary.getCreditName()); - - if(recordSummary.getCreatedDate() != null && recordSummary.getCreatedDate().getValue() != null) { - pojo.setCreation(DateUtils.formatDateISO8601(recordSummary.getCreatedDate().getValue().toGregorianCalendar().getTime())); + pojo.setName(recordSummary.getCreditName()); + + if (recordSummary.getCreatedDate() != null && recordSummary.getCreatedDate().getValue() != null) { + pojo.setCreation(DateUtils.formatDateISO8601(recordSummary.getCreatedDate().getValue().toGregorianCalendar().getTime())); } - - if(recordSummary.getLastModifiedDate() != null && recordSummary.getLastModifiedDate().getValue() != null) { + + if (recordSummary.getLastModifiedDate() != null && recordSummary.getLastModifiedDate().getValue() != null) { pojo.setLastModified(DateUtils.formatDateISO8601(recordSummary.getLastModifiedDate().getValue().toGregorianCalendar().getTime())); } - - if(recordSummary.getExternalIdentifiers() != null && recordSummary.getExternalIdentifiers().getExternalIdentifiers() != null) { + + if (recordSummary.getExternalIdentifiers() != null && recordSummary.getExternalIdentifiers().getExternalIdentifiers() != null) { List externalIdentifiers = new ArrayList<>(); - for(ExternalIdentifier ei : recordSummary.getExternalIdentifiers().getExternalIdentifiers()) { + for (ExternalIdentifier ei : recordSummary.getExternalIdentifiers().getExternalIdentifiers()) { ExternalIdentifiersSummary eis = new ExternalIdentifiersSummary(); eis.setCommonName(ei.getExternalIdType()); eis.setId(String.valueOf(ei.getPutCode())); @@ -176,10 +201,10 @@ public RecordSummaryPojo getRecordSummaryPojo(String orcid) { } pojo.setExternalIdentifiers(externalIdentifiers); } - - if(recordSummary.getEmployments() != null && recordSummary.getEmployments().getEmployments() != null) { + + if (recordSummary.getEmployments() != null && recordSummary.getEmployments().getEmployments() != null) { List affiliations = new ArrayList<>(); - for(Employment e : recordSummary.getEmployments().getEmployments()) { + for (Employment e : recordSummary.getEmployments().getEmployments()) { AffiliationSummary as = new AffiliationSummary(); as.setStartDate(e.getStartDate() == null ? null : e.getStartDate().toString()); as.setEndDate(e.getEndDate() == null ? null : e.getEndDate().toString()); @@ -192,51 +217,88 @@ public RecordSummaryPojo getRecordSummaryPojo(String orcid) { affiliations.add(as); } pojo.setEmploymentAffiliations(affiliations); - pojo.setEmploymentAffiliationsCount(recordSummary.getEmployments().getCount()); + pojo.setEmploymentAffiliationsCount(recordSummary.getEmployments().getCount()); } - - if(recordSummary.getProfessionalActivities() != null && recordSummary.getProfessionalActivities().getProfessionalActivities() != null) { + + if (recordSummary.getProfessionalActivities() != null && recordSummary.getProfessionalActivities().getProfessionalActivities() != null) { List professionalActivities = new ArrayList<>(); - for(ProfessionalActivity pa : recordSummary.getProfessionalActivities().getProfessionalActivities()) { + for (ProfessionalActivity pa : recordSummary.getProfessionalActivities().getProfessionalActivities()) { AffiliationSummary as = new AffiliationSummary(); as.setEndDate(pa.getEndDate() == null ? null : pa.getEndDate().toString()); as.setStartDate(pa.getStartDate() == null ? null : pa.getStartDate().toString()); as.setOrganizationName(pa.getOrganizationName()); as.setPutCode(pa.getPutCode()); - as.setRole(pa.getRole()); + as.setRole(pa.getRole()); as.setType(pa.getType()); as.setUrl(pa.getUrl()); as.setValidated(pa.isValidated()); professionalActivities.add(as); } - + pojo.setProfessionalActivities(professionalActivities); - pojo.setProfessionalActivitiesCount(recordSummary.getProfessionalActivities().getCount()); + pojo.setProfessionalActivitiesCount(recordSummary.getProfessionalActivities().getCount()); } - - - if(recordSummary.getFundings() != null) { + + if (recordSummary.getFundings() != null) { pojo.setSelfAssertedFunds(recordSummary.getFundings().getSelfAssertedCount()); pojo.setValidatedFunds(recordSummary.getFundings().getValidatedCount()); } - - if(recordSummary.getPeerReviews() != null) { + + if (recordSummary.getPeerReviews() != null) { pojo.setPeerReviewsTotal(recordSummary.getPeerReviews().getTotal()); pojo.setPeerReviewPublicationGrants(recordSummary.getPeerReviews().getPeerReviewPublicationGrants()); pojo.setSelfAssertedPeerReviews(recordSummary.getPeerReviews().getSelfAssertedCount()); } - - if(recordSummary.getWorks() != null) { + + if (recordSummary.getWorks() != null) { pojo.setSelfAssertedWorks(recordSummary.getWorks().getSelfAssertedCount()); pojo.setValidatedWorks(recordSummary.getWorks().getValidatedCount()); } - + + if (recordSummary.getEducationQualifications() != null && recordSummary.getEducationQualifications().getEducationQualifications() != null) { + List educationQualifications = new ArrayList<>(); + for (EducationQualification eq : recordSummary.getEducationQualifications().getEducationQualifications()) { + AffiliationSummary as = new AffiliationSummary(); + as.setEndDate(eq.getEndDate() == null ? null : eq.getEndDate().toString()); + as.setStartDate(eq.getStartDate() == null ? null : eq.getStartDate().toString()); + as.setOrganizationName(eq.getOrganizationName()); + as.setPutCode(eq.getPutCode()); + as.setRole(eq.getRole()); + as.setType(eq.getType()); + as.setUrl(eq.getUrl()); + as.setValidated(eq.isValidated()); + educationQualifications.add(as); + } + + pojo.setEducationQualifications(educationQualifications); + pojo.setEducationQualificationsCount(recordSummary.getEducationQualifications().getCount()); + } + + if (recordSummary.getResearchResources() != null) { + pojo.setSelfAssertedResearchResources(recordSummary.getResearchResources().getSelfAssertedCount()); + pojo.setValidatedResearchResources(recordSummary.getResearchResources().getValidatedCount()); + } + + if (recordSummary.getEmailDomains() != null) { + List emailDomains = new ArrayList(); + if (recordSummary.getEmailDomains() != null && recordSummary.getEmailDomains().getEmailDomains() != null) { + for (EmailDomain ed : recordSummary.getEmailDomains().getEmailDomains()) { + EmailDomainSummary eds = new EmailDomainSummary(); + eds.setValue(ed.getValue()); + eds.setCreatedDate(ed.getCreatedDate().toFuzzyDate().toString()); + eds.setLastModified(ed.getLastModified().toFuzzyDate().toString()); + } + } + pojo.setEmailDomains(emailDomains); + pojo.setEmailDomainsCount(recordSummary.getEmailDomains().getCount()); + } + return pojo; - } - + } + public void generateAffiliationsSummary(RecordSummary recordSummary, String orcid) { - Map>> affiliationsMap = affiliationsManagerReadOnly.getGroupedAffiliations(orcid, - true); + Map>> affiliationsMap = affiliationsManagerReadOnly + .getGroupedAffiliations(orcid, true); // EMPLOYMENT List> employmentGroups = affiliationsMap.get(AffiliationType.EMPLOYMENT); @@ -261,15 +323,15 @@ public void generateAffiliationsSummary(RecordSummary recordSummary, String orci e.setValidated(!SourceUtils.isSelfAsserted(t.getSource(), orcid)); employmentsTop3.add(e); }); - + Employments e = new Employments(); e.setCount(preferredEmployments.size()); recordSummary.setEmployments(e); - if(!employmentsTop3.isEmpty()) { + if (!employmentsTop3.isEmpty()) { e.setEmployments(employmentsTop3); - } + } recordSummary.setEmployments(e); - + // PROFESIONAL ACTIVITIES List> profesionalActivitesGroups = new ArrayList<>(); if (affiliationsMap.containsKey(AffiliationType.DISTINCTION)) { @@ -284,6 +346,7 @@ public void generateAffiliationsSummary(RecordSummary recordSummary, String orci if (affiliationsMap.containsKey(AffiliationType.SERVICE)) { profesionalActivitesGroups.addAll(affiliationsMap.get(AffiliationType.SERVICE)); } + List preferredProfesionalActivities = new ArrayList<>(); for (AffiliationGroup group : profesionalActivitesGroups) { preferredProfesionalActivities.add(getDefaultAffiliationFromGroup(group)); @@ -299,7 +362,7 @@ public void generateAffiliationsSummary(RecordSummary recordSummary, String orci p.setStartDate(t.getStartDate()); p.setEndDate(t.getEndDate()); p.setRole(t.getRoleTitle()); - if(t instanceof DistinctionSummary) { + if (t instanceof DistinctionSummary) { p.setType(AffiliationType.DISTINCTION.value()); } else if (t instanceof InvitedPositionSummary) { p.setType(AffiliationType.INVITED_POSITION.value()); @@ -314,20 +377,63 @@ public void generateAffiliationsSummary(RecordSummary recordSummary, String orci }); ProfessionalActivities pa = new ProfessionalActivities(); pa.setCount(preferredProfesionalActivities.size()); - if(!professionalActivitiesTop3.isEmpty()) { + if (!professionalActivitiesTop3.isEmpty()) { pa.setProfessionalActivities(professionalActivitiesTop3); } + recordSummary.setProfessionalActivities(pa); + + // EDUCATION Y QUALIFICATION + List> educationQualificationsGroups = new ArrayList<>(); + if (affiliationsMap.containsKey(AffiliationType.EDUCATION)) { + educationQualificationsGroups.addAll(affiliationsMap.get(AffiliationType.EDUCATION)); + } + if (affiliationsMap.containsKey(AffiliationType.QUALIFICATION)) { + educationQualificationsGroups.addAll(affiliationsMap.get(AffiliationType.QUALIFICATION)); + } + + List preferredEducationQualifications = new ArrayList<>(); + for (AffiliationGroup group : educationQualificationsGroups) { + preferredEducationQualifications.add(getDefaultAffiliationFromGroup(group)); + } + // Sort them by end date by default + sortAffiliationsByEndDate(preferredEducationQualifications); + + List educationQualificationsTop3 = new ArrayList(); + preferredEducationQualifications.stream().limit(3).forEach(t -> { + EducationQualification eq = new EducationQualification(); + eq.setOrganizationName((t.getOrganization() == null || StringUtils.isBlank(t.getOrganization().getName())) ? null : t.getOrganization().getName()); + eq.setPutCode(t.getPutCode()); + eq.setStartDate(t.getStartDate()); + eq.setEndDate(t.getEndDate()); + eq.setRole(t.getRoleTitle()); + if (t instanceof EducationSummary) { + eq.setType(AffiliationType.EDUCATION.value()); + } else if (t instanceof QualificationSummary) { + eq.setType(AffiliationType.QUALIFICATION.value()); + } + eq.setUrl((t.getUrl() == null || StringUtils.isBlank(t.getUrl().getValue())) ? null : t.getUrl().getValue()); + eq.setValidated(!SourceUtils.isSelfAsserted(t.getSource(), orcid)); + educationQualificationsTop3.add(eq); + }); + + EducationQualifications eqList = new EducationQualifications(); + eqList.setCount(preferredEducationQualifications.size()); + if (!educationQualificationsTop3.isEmpty()) { + eqList.setEducationQualifications(educationQualificationsTop3); + } + + recordSummary.setEducationQualifications(eqList); } - + public void generateExternalIdentifiersSummary(RecordSummary recordSummary, String orcid) { PersonExternalIdentifiers personExternalIdentifiers = externalIdentifierManagerReadOnly.getPublicExternalIdentifiers(orcid); - if(personExternalIdentifiers == null || personExternalIdentifiers.getExternalIdentifiers().isEmpty()) { + if (personExternalIdentifiers == null || personExternalIdentifiers.getExternalIdentifiers().isEmpty()) { return; } ExternalIdentifiers eis = new ExternalIdentifiers(); eis.setExternalIdentifiers(new ArrayList<>()); - for(PersonExternalIdentifier pei : personExternalIdentifiers.getExternalIdentifiers()) { + for (PersonExternalIdentifier pei : personExternalIdentifiers.getExternalIdentifiers()) { ExternalIdentifier ei = new ExternalIdentifier(); ei.setExternalIdType(pei.getType()); ei.setExternalIdUrl((pei.getUrl() == null || StringUtils.isEmpty(pei.getUrl().getValue())) ? null : pei.getUrl().getValue()); @@ -337,21 +443,21 @@ public void generateExternalIdentifiersSummary(RecordSummary recordSummary, Stri eis.getExternalIdentifiers().add(ei); } recordSummary.setExternalIdentifiers(eis); - } - + } + public void generateWorksSummary(RecordSummary recordSummary, String orcid) { org.orcid.jaxb.model.v3.release.record.summary.Works works = worksCacheManager.getGroupedWorks(orcid); Iterator workGroupIt = works.getWorkGroup().iterator(); while (workGroupIt.hasNext()) { WorkGroup workGroup = workGroupIt.next(); Iterator summariesIt = workGroup.getWorkSummary().iterator(); - while(summariesIt.hasNext()) { + while (summariesIt.hasNext()) { WorkSummary w = summariesIt.next(); - if(!Visibility.PUBLIC.equals(w.getVisibility())) { + if (!Visibility.PUBLIC.equals(w.getVisibility())) { summariesIt.remove(); } } - if(workGroup.getActivities() == null || workGroup.getActivities().isEmpty()) { + if (workGroup.getActivities() == null || workGroup.getActivities().isEmpty()) { workGroupIt.remove(); } } @@ -362,9 +468,10 @@ public void generateWorksSummary(RecordSummary recordSummary, String orcid) { worksModel.setValidatedCount(validAndSelfAssertedStats.getLeft()); recordSummary.setWorks(worksModel); } - + public void generateFundingSummary(RecordSummary recordSummary, String orcid) { - org.orcid.jaxb.model.v3.release.record.summary.Fundings fundingGroups = profileFundingManagerReadOnly.groupFundings(profileFundingManagerReadOnly.getFundingSummaryList(orcid), true); + org.orcid.jaxb.model.v3.release.record.summary.Fundings fundingGroups = profileFundingManagerReadOnly + .groupFundings(profileFundingManagerReadOnly.getFundingSummaryList(orcid), true); Pair validAndSelfAssertedStats = calculateSelfAssertedAndValidated(fundingGroups, orcid); Fundings fundingsModel = new Fundings(); @@ -391,10 +498,57 @@ public void generatePeerReviewSummary(RecordSummary recordSummary, String orcid) PeerReviews pr = new PeerReviews(); pr.setPeerReviewPublicationGrants(peerReviewMinimizedSummaryList.size()); pr.setSelfAssertedCount(selfAssertedPeerReviews); - pr.setTotal(totalReviewsCount); + pr.setTotal(totalReviewsCount); recordSummary.setPeerReviews(pr); } + public void generateResearchResourcesSummary(RecordSummary recordSummary, String orcid) { + org.orcid.jaxb.model.v3.release.record.summary.ResearchResources researchResourcesGroups = researchResourceManagerReadOnly + .groupResearchResources(researchResourceManagerReadOnly.getResearchResourceSummaryList(orcid), true); + Pair validAndSelfAssertedStats = calculateSelfAssertedAndValidated(researchResourcesGroups, orcid); + + ResearchResources researchResourceModel = new ResearchResources(); + researchResourceModel.setSelfAssertedCount(validAndSelfAssertedStats.getRight()); + researchResourceModel.setValidatedCount(validAndSelfAssertedStats.getLeft()); + recordSummary.setResearchResources(researchResourceModel); + } + + public void generateEmailDomainsSummary(RecordSummary recordSummary, String orcid) { + // Fill email domains + List emailDomains = null; + if (Features.EMAIL_DOMAINS.isActive()) { + emailDomains = profileEmailDomainManagerReadOnly.getPublicEmailDomains(orcid); + List edList = new ArrayList(); + if (emailDomains != null && !emailDomains.isEmpty()) { + + EmailDomain ed = null; + for (ProfileEmailDomainEntity ped : emailDomains) { + ed = new EmailDomain(); + ed.setValue(ped.getEmailDomain()); + ed.setCreatedDate(Date.valueOf(ped.getDateCreated())); + ed.setLastModified(Date.valueOf(ped.getLastModified())); + edList.add(ed); + } + } + + List emailDomainsTop3 = new ArrayList(); + edList.stream().limit(3).forEach(t -> { + EmailDomain ed = new EmailDomain(); + ed.setValue(t.getValue()); + ed.setCreatedDate(t.getCreatedDate()); + ed.setLastModified(t.getLastModified()); + emailDomainsTop3.add(ed); + }); + + EmailDomains eds = new EmailDomains(); + eds.setCount(edList.size()); + if (!emailDomainsTop3.isEmpty()) { + eds.setEmailDomains(emailDomainsTop3); + } + recordSummary.setEmailDomains(eds); + } + } + private Pair calculateSelfAssertedAndValidated(GroupsContainer c, String orcid) { Integer validated = 0; Integer selfAsserted = 0; @@ -419,7 +573,8 @@ private Pair calculateSelfAssertedAndValidated(GroupsContainer return Pair.of(validated, selfAsserted); } - private org.orcid.jaxb.model.v3.release.record.summary.AffiliationSummary getDefaultAffiliationFromGroup(AffiliationGroup group) { + private org.orcid.jaxb.model.v3.release.record.summary.AffiliationSummary getDefaultAffiliationFromGroup( + AffiliationGroup group) { org.orcid.jaxb.model.v3.release.record.summary.AffiliationSummary defaultAffiliation = null; Long maxDisplayIndex = null; for (org.orcid.jaxb.model.v3.release.record.summary.AffiliationSummary as : group.getActivities()) { @@ -456,7 +611,7 @@ private void sortAffiliationsByEndDate(List s.setEndDate(null)); } - + private String getCacheKey(String orcid) { return orcid + "-summary"; } diff --git a/orcid-core/src/main/java/org/orcid/core/model/EducationQualification.java b/orcid-core/src/main/java/org/orcid/core/model/EducationQualification.java new file mode 100644 index 00000000000..bdd2de9f6e8 --- /dev/null +++ b/orcid-core/src/main/java/org/orcid/core/model/EducationQualification.java @@ -0,0 +1,119 @@ +package org.orcid.core.model; + +import java.util.Objects; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.orcid.jaxb.model.v3.release.common.FuzzyDate; + +import io.swagger.v3.oas.annotations.media.Schema; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "putCode", "type", "organizationName", "role", "url", "startDate", "endDate", "validated" }) +@XmlRootElement(name = "education-qualification", namespace = "http://www.orcid.org/ns/summary") +@Schema(description = "Education Qualification") +public class EducationQualification { + @XmlElement(name = "put-code", namespace = "http://www.orcid.org/ns/summary") + protected Long putCode; + @XmlElement(name = "start-date", namespace = "http://www.orcid.org/ns/common") + protected FuzzyDate startDate; + @XmlElement(name = "end-date", namespace = "http://www.orcid.org/ns/common") + protected FuzzyDate endDate; + @XmlElement(name = "type", namespace = "http://www.orcid.org/ns/summary") + protected String type; + @XmlElement(name = "organization-name", namespace = "http://www.orcid.org/ns/summary") + protected String organizationName; + @XmlElement(name = "role", namespace = "http://www.orcid.org/ns/summary") + protected String role; + @XmlElement(name = "url", namespace = "http://www.orcid.org/ns/summary") + protected String url; + @XmlElement(name = "validated", namespace = "http://www.orcid.org/ns/summary") + protected boolean validated; + + public Long getPutCode() { + return putCode; + } + + public void setPutCode(Long putCode) { + this.putCode = putCode; + } + + public FuzzyDate getStartDate() { + return startDate; + } + + public void setStartDate(FuzzyDate startDate) { + this.startDate = startDate; + } + + public FuzzyDate getEndDate() { + return endDate; + } + + public void setEndDate(FuzzyDate endDate) { + this.endDate = endDate; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getOrganizationName() { + return organizationName; + } + + public void setOrganizationName(String organizationName) { + this.organizationName = organizationName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public boolean isValidated() { + return validated; + } + + public void setValidated(boolean validated) { + this.validated = validated; + } + + @Override + public int hashCode() { + return Objects.hash(endDate, organizationName, putCode, role, startDate, type, url, validated); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EducationQualification other = (EducationQualification) obj; + return Objects.equals(endDate, other.endDate) && Objects.equals(organizationName, other.organizationName) && Objects.equals(putCode, other.putCode) + && Objects.equals(role, other.role) && Objects.equals(startDate, other.startDate) && Objects.equals(type, other.type) && Objects.equals(url, other.url) + && validated == other.validated; + } +} diff --git a/orcid-core/src/main/java/org/orcid/core/model/EducationQualifications.java b/orcid-core/src/main/java/org/orcid/core/model/EducationQualifications.java new file mode 100644 index 00000000000..f20f1a9e3dd --- /dev/null +++ b/orcid-core/src/main/java/org/orcid/core/model/EducationQualifications.java @@ -0,0 +1,62 @@ +package org.orcid.core.model; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import io.swagger.v3.oas.annotations.media.Schema; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "count", "educationQualifications" }) +@XmlRootElement(name = "education-qualifications", namespace = "http://www.orcid.org/ns/summary") +@Schema(description = "Education qualifications list") +public class EducationQualifications implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + @XmlElement(name = "count", namespace = "http://www.orcid.org/ns/summary") + private Integer count; + @XmlElement(name = "education-qualification", namespace = "http://www.orcid.org/ns/summary") + private List educationQualifications; + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public List getEducationQualifications() { + return educationQualifications; + } + + public void setEducationQualifications(List educationQualifications ) { + this.educationQualifications = educationQualifications ; + } + + @Override + public int hashCode() { + return Objects.hash(count, educationQualifications); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EducationQualifications other = (EducationQualifications) obj; + return Objects.equals(count, other.count) && Objects.equals(educationQualifications, other.educationQualifications); + } + +} diff --git a/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java b/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java new file mode 100644 index 00000000000..a31928c6841 --- /dev/null +++ b/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java @@ -0,0 +1,68 @@ +package org.orcid.core.model; + +import java.util.Objects; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.orcid.jaxb.model.v3.release.common.FuzzyDate; +import org.orcid.pojo.ajaxForm.Date; + +import io.swagger.v3.oas.annotations.media.Schema; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "value","createdDate", "lastModified"}) +@XmlRootElement(name = "education-qualification", namespace = "http://www.orcid.org/ns/summary") +@Schema(description = "Education Qualification") +public class EmailDomain { + @XmlElement(name = "value", namespace = "http://www.orcid.org/ns/summary") + protected String value; + @XmlElement(name = "created-date", namespace = "http://www.orcid.org/ns/common") + protected Date createdDate; + @XmlElement(name = "last-modified-date", namespace = "http://www.orcid.org/ns/common") + protected Date lastModified; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Date getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(Date createdDate) { + this.createdDate = createdDate; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + @Override + public int hashCode() { + return Objects.hash(value, createdDate, lastModified); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EmailDomain other = (EmailDomain) obj; + return Objects.equals(createdDate, other.createdDate) && Objects.equals(lastModified, other.lastModified) && Objects.equals(value, other.value); + } +} diff --git a/orcid-core/src/main/java/org/orcid/core/model/EmailDomains.java b/orcid-core/src/main/java/org/orcid/core/model/EmailDomains.java new file mode 100644 index 00000000000..138c28add94 --- /dev/null +++ b/orcid-core/src/main/java/org/orcid/core/model/EmailDomains.java @@ -0,0 +1,62 @@ +package org.orcid.core.model; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import io.swagger.v3.oas.annotations.media.Schema; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "count", "emailDomains" }) +@XmlRootElement(name = "email-domains", namespace = "http://www.orcid.org/ns/summary") +@Schema(description = "Email domains list") +public class EmailDomains implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + @XmlElement(name = "count", namespace = "http://www.orcid.org/ns/summary") + private Integer count; + @XmlElement(name = "email-domain", namespace = "http://www.orcid.org/ns/summary") + private List emailDomains; + + public Integer getCount() { + return count; + } + + public void setCount(Integer count) { + this.count = count; + } + + public List getEmailDomains() { + return emailDomains; + } + + public void setEmailDomains(List emailDomains ) { + this.emailDomains = emailDomains ; + } + + @Override + public int hashCode() { + return Objects.hash(count, emailDomains); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EmailDomains other = (EmailDomains) obj; + return Objects.equals(count, other.count) && Objects.equals(emailDomains, other.emailDomains); + } + +} diff --git a/orcid-core/src/main/java/org/orcid/core/model/RecordSummary.java b/orcid-core/src/main/java/org/orcid/core/model/RecordSummary.java index 0dba0f03e5c..cc8189048da 100644 --- a/orcid-core/src/main/java/org/orcid/core/model/RecordSummary.java +++ b/orcid-core/src/main/java/org/orcid/core/model/RecordSummary.java @@ -20,7 +20,7 @@ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(propOrder = { "createdDate", "lastModifiedDate", "creditName", "orcidIdentifier", "externalIdentifiers", "employments", "professionalActivities", "fundings", - "works", "peerReviews" }) + "works", "peerReviews", "emailDomains", "educationQualifications", "researchResources" }) @XmlRootElement(name = "record-summary", namespace = "http://www.orcid.org/ns/summary") @Schema(description = "Record summary") public class RecordSummary implements Serializable { @@ -52,6 +52,13 @@ public class RecordSummary implements Serializable { @XmlElement(name = "peer-reviews", namespace = "http://www.orcid.org/ns/summary") private PeerReviews peerReviews; + @XmlElement(name = "education-qualifications", namespace = "http://www.orcid.org/ns/summary") + private EducationQualifications educationQualifications; + @XmlElement(name = "research-resources", namespace = "http://www.orcid.org/ns/summary") + private ResearchResources researchResources; + @XmlElement(name = "email-domains", namespace = "http://www.orcid.org/ns/summary") + private EmailDomains emailDomains; + public OrcidIdentifier getOrcidIdentifier() { return orcidIdentifier; } @@ -132,10 +139,34 @@ public void setPeerReviews(PeerReviews peerReviews) { this.peerReviews = peerReviews; } + public EducationQualifications getEducationQualifications() { + return educationQualifications; + } + + public void setEducationQualifications(EducationQualifications educationQualifications) { + this.educationQualifications = educationQualifications; + } + + public ResearchResources getResearchResources() { + return researchResources; + } + + public void setResearchResources(ResearchResources researchResources) { + this.researchResources = researchResources; + } + + public EmailDomains getEmailDomains() { + return emailDomains; + } + + public void setEmailDomains(EmailDomains emailDomains) { + this.emailDomains = emailDomains; + } + @Override public int hashCode() { return Objects.hash(createdDate, creditName, employments, externalIdentifiers, fundings, lastModifiedDate, orcidIdentifier, orcidUrlManager, peerReviews, - professionalActivities, works); + professionalActivities, works, emailDomains, educationQualifications, researchResources ); } @Override @@ -151,6 +182,8 @@ public boolean equals(Object obj) { && Objects.equals(externalIdentifiers, other.externalIdentifiers) && Objects.equals(fundings, other.fundings) && Objects.equals(lastModifiedDate, other.lastModifiedDate) && Objects.equals(orcidIdentifier, other.orcidIdentifier) && Objects.equals(orcidUrlManager, other.orcidUrlManager) && Objects.equals(peerReviews, other.peerReviews) - && Objects.equals(professionalActivities, other.professionalActivities) && Objects.equals(works, other.works); - } + && Objects.equals(professionalActivities, other.professionalActivities) && Objects.equals(works, other.works) + && Objects.equals(educationQualifications, other.educationQualifications) && Objects.equals(researchResources, other.researchResources) + && Objects.equals(emailDomains, other.emailDomains) ; + } } diff --git a/orcid-core/src/main/java/org/orcid/core/model/ResearchResources.java b/orcid-core/src/main/java/org/orcid/core/model/ResearchResources.java new file mode 100644 index 00000000000..3748e41b223 --- /dev/null +++ b/orcid-core/src/main/java/org/orcid/core/model/ResearchResources.java @@ -0,0 +1,18 @@ +package org.orcid.core.model; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlRootElement; + +import io.swagger.v3.oas.annotations.media.Schema; + +@XmlRootElement(name = "research-resources", namespace = "http://www.orcid.org/ns/summary") +@Schema(description = "Research resources") +public class ResearchResources extends ItemsCount implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java b/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java new file mode 100644 index 00000000000..4513d3db408 --- /dev/null +++ b/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java @@ -0,0 +1,56 @@ +package org.orcid.pojo.summary; + +import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity; +import org.orcid.pojo.ajaxForm.PojoUtil; + +public class EmailDomainSummary { + private String value; + private String createdDate; + private String lastModified; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(String createdDate) { + this.createdDate = createdDate; + } + + public String getLastModified() { + return lastModified; + } + + public void setLastModified(String lastModified) { + this.lastModified = lastModified; + } + + + public static EmailDomainSummary valueOf(ProfileEmailDomainEntity pem) { + EmailDomainSummary form = new EmailDomainSummary(); + + if (pem != null) { + if(!PojoUtil.isEmpty(pem.getEmailDomain())) { + form.setValue(pem.getEmailDomain()); + } + + if (pem.getDateCreated() != null) { + form.setCreatedDate(org.orcid.pojo.ajaxForm.Date.valueOf(pem.getDateCreated()).toFuzzyDate().toString()); + } + + if (pem.getLastModified() !=null) { + form.setLastModified(org.orcid.pojo.ajaxForm.Date.valueOf(pem.getLastModified()).toFuzzyDate().toString()); + } + } + return form; + } + + +} diff --git a/orcid-core/src/main/java/org/orcid/pojo/summary/RecordSummaryPojo.java b/orcid-core/src/main/java/org/orcid/pojo/summary/RecordSummaryPojo.java index 1628c45bbed..b889c1547b1 100644 --- a/orcid-core/src/main/java/org/orcid/pojo/summary/RecordSummaryPojo.java +++ b/orcid-core/src/main/java/org/orcid/pojo/summary/RecordSummaryPojo.java @@ -27,6 +27,13 @@ public class RecordSummaryPojo { private int professionalActivitiesCount; private List externalIdentifiers; private String status; + private List educationQualifications; + private int educationQualificationsCount; + private int validatedResearchResources; + private int selfAssertedResearchResources; + + private List emailDomains; + private int emailDomainsCount; public String getName() { return name; @@ -163,4 +170,53 @@ public String getStatus() { public void setStatus(String status) { this.status = status; } + + public List getEducationQualifications() { + return educationQualifications; + } + + public void setEducationQualifications(List educationQualifications) { + this.educationQualifications = educationQualifications; + } + + public int getEducationQualificationsCount() { + return educationQualificationsCount; + } + + public void setEducationQualificationsCount(int educationQualificationsCount) { + this.educationQualificationsCount = educationQualificationsCount; + } + + public int getValidatedResearchResources() { + return validatedResearchResources; + } + + public void setValidatedResearchResources(int validatedResearchResources) { + this.validatedResearchResources = validatedResearchResources; + } + + public int getSelfAssertedResearchResources() { + return selfAssertedResearchResources; + } + + public void setSelfAssertedResearchResources(int selfAssertedResearchResources) { + this.selfAssertedResearchResources = selfAssertedResearchResources; + } + + public List getEmailDomains() { + return emailDomains; + } + + public void setEmailDomains(List emailDomains) { + this.emailDomains = emailDomains; + } + + public int getEmailDomainsCount() { + return emailDomainsCount; + } + + public void setEmailDomainsCount(int emailDomainsCount) { + this.emailDomainsCount = emailDomainsCount; + } + } diff --git a/orcid-core/src/test/java/org/orcid/core/common/manager/SummaryManagerTest.java b/orcid-core/src/test/java/org/orcid/core/common/manager/SummaryManagerTest.java index 509625b5407..61e4ac2e8f1 100644 --- a/orcid-core/src/test/java/org/orcid/core/common/manager/SummaryManagerTest.java +++ b/orcid-core/src/test/java/org/orcid/core/common/manager/SummaryManagerTest.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; +import javax.annotation.Resource; import javax.xml.datatype.XMLGregorianCalendar; import org.junit.Before; @@ -25,9 +26,12 @@ import org.orcid.core.manager.v3.read_only.AffiliationsManagerReadOnly; import org.orcid.core.manager.v3.read_only.ExternalIdentifierManagerReadOnly; import org.orcid.core.manager.v3.read_only.PeerReviewManagerReadOnly; +import org.orcid.core.manager.v3.read_only.ProfileEmailDomainManagerReadOnly; import org.orcid.core.manager.v3.read_only.ProfileFundingManagerReadOnly; import org.orcid.core.manager.v3.read_only.RecordManagerReadOnly; import org.orcid.core.manager.v3.read_only.RecordNameManagerReadOnly; +import org.orcid.core.manager.v3.read_only.ResearchResourceManagerReadOnly; +import org.orcid.core.model.EmailDomains; import org.orcid.core.model.ProfessionalActivity; import org.orcid.core.model.RecordSummary; import org.orcid.jaxb.model.v3.release.common.CreatedDate; @@ -61,10 +65,13 @@ import org.orcid.jaxb.model.v3.release.record.summary.InvitedPositionSummary; import org.orcid.jaxb.model.v3.release.record.summary.MembershipSummary; import org.orcid.jaxb.model.v3.release.record.summary.QualificationSummary; +import org.orcid.jaxb.model.v3.release.record.summary.ResearchResourceSummary; import org.orcid.jaxb.model.v3.release.record.summary.ServiceSummary; import org.orcid.jaxb.model.v3.release.record.summary.WorkGroup; import org.orcid.jaxb.model.v3.release.record.summary.WorkSummary; import org.orcid.jaxb.model.v3.release.record.summary.Works; +import org.orcid.jaxb.model.v3.release.record.summary.ResearchResources; +import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity; import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.pojo.PeerReviewMinimizedSummary; import org.orcid.pojo.summary.RecordSummaryPojo; @@ -103,6 +110,12 @@ public class SummaryManagerTest { @Mock private WorksCacheManager worksCacheManagerMock; + + @Mock + private ResearchResourceManagerReadOnly researchResourceManagerReadOnlyMock; + + @Mock + private ProfileEmailDomainManagerReadOnly profileEmailDomainManagerReadOnlyMock; @Before public void setUp() { @@ -143,7 +156,20 @@ public void setUp() { // Set peer reviews Mockito.when(peerReviewManagerReadOnlyMock.getPeerReviewMinimizedSummaryList(Mockito.eq(ORCID), Mockito.eq(true))).thenReturn(getPeerReviewSummaryList()); ReflectionTestUtils.setField(manager, "peerReviewManagerReadOnly", peerReviewManagerReadOnlyMock); + + + // Set ResearchResources + ResearchResources researchResources = getResearchResources(); + Mockito.when(researchResourceManagerReadOnlyMock.getResearchResourceSummaryList(Mockito.eq(ORCID))).thenReturn(new ArrayList()); + Mockito.when(researchResourceManagerReadOnlyMock.groupResearchResources(Mockito.anyList(), Mockito.eq(true))).thenReturn(researchResources); + ReflectionTestUtils.setField(manager, "researchResourceManagerReadOnly", researchResourceManagerReadOnlyMock); + // Set EmailDomains + EmailDomains emailDomains = getEmailDomains(); + Mockito.when(profileEmailDomainManagerReadOnlyMock.getPublicEmailDomains(Mockito.eq(ORCID))).thenReturn(new ArrayList()); + ReflectionTestUtils.setField(manager, "profileEmailDomainManagerReadOnly", profileEmailDomainManagerReadOnlyMock); + + // Set metadata OrcidIdentifier oi = new OrcidIdentifier(); oi.setUri("https://test.orcid.org/0000-0000-0000-0000"); @@ -574,6 +600,20 @@ private PersonExternalIdentifiers getPersonExternalIdentifiers() { peis.getExternalIdentifiers().add(pei); return peis; } + + private ResearchResources getResearchResources() { + ResearchResources researchResources = new ResearchResources(); + + return researchResources; + } + + private EmailDomains getEmailDomains() { + EmailDomains emailDomains = new EmailDomains(); + + return emailDomains; + } + + private List> getAffiliations(AffiliationType affiliationType) { List> affiliationGroups = new ArrayList<>(); diff --git a/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java b/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java index a2de2996071..72c5a541aae 100644 --- a/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java +++ b/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java @@ -20,6 +20,7 @@ import org.orcid.jaxb.model.v3.release.common.Month; import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier; import org.orcid.jaxb.model.v3.release.common.Year; +import org.orcid.pojo.ajaxForm.Date; import org.orcid.utils.DateUtils; public class RecordSummaryMarshallingTest { @@ -29,7 +30,6 @@ public void marshallingTest() throws JAXBException, IOException { JAXBContext context = JAXBContext.newInstance(new Class[] { RecordSummary.class }); Marshaller marshaller = context.createMarshaller(); String expectedText = IOUtils.toString(getClass().getResourceAsStream("summary-3.0.xml"), StandardCharsets.UTF_8); - RecordSummary recordSummary = getRecordSummary(); StringWriter stringWriter = new StringWriter(); marshaller.marshal(recordSummary, stringWriter); @@ -80,6 +80,8 @@ private RecordSummary getRecordSummary() { fundings.setValidatedCount(1); record.setFundings(fundings); + + Works works = new Works(); works.setSelfAssertedCount(0); works.setValidatedCount(1); @@ -91,6 +93,25 @@ private RecordSummary getRecordSummary() { peerReviews.setTotal(6); record.setPeerReviews(peerReviews); + //Set email domains + EmailDomains emailDomains = new EmailDomains(); + emailDomains.setCount(4); + emailDomains.setEmailDomains(new ArrayList()); + emailDomains.getEmailDomains().add(getEmailDomain("sometrusted.org", getEmailDomainCreatedDate(), getEmailDomainLastModified())); + record.setEmailDomains(emailDomains); + + //Set education/qualifications + EducationQualifications educationQualifications = new EducationQualifications(); + educationQualifications.setCount(6); + educationQualifications.setEducationQualifications(new ArrayList()); + educationQualifications.getEducationQualifications().add(getEducationQualification(1, "Org # 1", "Fake role title", "https://test.orcid.org/", "education", false)); + record.setEducationQualifications(educationQualifications); + //Set research resources + ResearchResources researchResources = new ResearchResources(); + researchResources.setSelfAssertedCount(0); + researchResources.setValidatedCount(1); + record.setResearchResources(researchResources); + return record; } @@ -129,6 +150,27 @@ private ProfessionalActivity getProfessionalActivity(int putCode, String role, S return pa; } + private EducationQualification getEducationQualification(int putCode, String role, String org, String url, String type, boolean validated) { + EducationQualification eq = new EducationQualification(); + eq.setPutCode(Long.valueOf(putCode)); + eq.setEndDate(getEndDate()); + eq.setStartDate(getStartDate()); + eq.setOrganizationName(org); + eq.setRole(role); + eq.setUrl(url); + eq.setValidated(validated); + eq.setType(type); + return eq; + } + + private EmailDomain getEmailDomain(String domainValue, Date created, Date modified) { + EmailDomain emailDomain = new EmailDomain(); + emailDomain.setValue(domainValue); + //emailDomain.setCreatedDate(created); + //emailDomain.setLastModified(modified); + return emailDomain; + } + private FuzzyDate getEndDate() { return new FuzzyDate(new Year(2024), new Month(12), new Day(31)); } @@ -136,4 +178,13 @@ private FuzzyDate getEndDate() { private FuzzyDate getStartDate() { return new FuzzyDate(new Year(2020), new Month(1), new Day(1)); } + + + private Date getEmailDomainCreatedDate() { + return Date.valueOf(new FuzzyDate(new Year(2020), new Month(1), new Day(1))); + } + + private Date getEmailDomainLastModified() { + return Date.valueOf(new FuzzyDate(new Year(2020), new Month(1), new Day(1))); + } } diff --git a/orcid-core/src/test/resources/org/orcid/core/model/summary-3.0.xml b/orcid-core/src/test/resources/org/orcid/core/model/summary-3.0.xml index ee782257c6d..d1b1400022d 100644 --- a/orcid-core/src/test/resources/org/orcid/core/model/summary-3.0.xml +++ b/orcid-core/src/test/resources/org/orcid/core/model/summary-3.0.xml @@ -1 +1 @@ -2024-01-01T12:00:002024-01-01T12:00:00User credited namehttps://orcid.org/8888-8888-8888-88808888-8888-8888-8880orcid.org1Scopus1https://test.orcid.org/1true2ResearcherID2https://test.orcid.org/2true3Other3https://test.orcid.org/3true51employmentFake role title 1Org # 1https://test.orcid.org/12020010120241231false2employmentFake role title 2Org # 2https://test.orcid.org/22020010120241231false3employmentFake role title 3Org # 3https://test.orcid.org/32020010120241231true51distinctionFake role titleOrg # 1https://test.orcid.org/2020010120241231false0101606 \ No newline at end of file +2024-01-01T12:00:002024-01-01T12:00:00User credited namehttps://orcid.org/8888-8888-8888-88808888-8888-8888-8880orcid.org1Scopus1https://test.orcid.org/1true2ResearcherID2https://test.orcid.org/2true3Other3https://test.orcid.org/3true51employmentFake role title 1Org # 1https://test.orcid.org/12020010120241231false2employmentFake role title 2Org # 2https://test.orcid.org/22020010120241231false3employmentFake role title 3Org # 3https://test.orcid.org/32020010120241231true51distinctionFake role titleOrg # 1https://test.orcid.org/2020010120241231false01016064sometrusted.org61educationFake role titleOrg # 1https://test.orcid.org/2020010120241231false01 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8db2798b0da..102707e2b93 100644 --- a/pom.xml +++ b/pom.xml @@ -918,7 +918,7 @@ the software. org.orcid orcid-model - 3.3.0 + 3.3.1 org.orcid From 436368cea5ddc644a2406a55f5ee1d9aced9c3fe Mon Sep 17 00:00:00 2001 From: github actions Date: Tue, 17 Sep 2024 15:36:53 +0000 Subject: [PATCH 11/36] v2.65.1 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 676a7bc6c21..6a8aee8d89e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.65.1 - 2024-09-17 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.0...v2.65.1) + ## v2.65.0 - 2024-09-13 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.64.6...v2.65.0) From a321ebf539a795140421ee79987a541f087fd26f Mon Sep 17 00:00:00 2001 From: andrej romanov <50377758+auumgn@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:14:45 +0300 Subject: [PATCH 12/36] new email domains should have a default profile visibility (#7088) * new email domains should have a default profile visibility * use cache instead of database call --- .../impl/ProfileEmailDomainManagerImpl.java | 41 ++++--------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/orcid-core/src/main/java/org/orcid/core/manager/v3/impl/ProfileEmailDomainManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/manager/v3/impl/ProfileEmailDomainManagerImpl.java index c2eb6ae2eb9..ecbf129bd04 100644 --- a/orcid-core/src/main/java/org/orcid/core/manager/v3/impl/ProfileEmailDomainManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/manager/v3/impl/ProfileEmailDomainManagerImpl.java @@ -1,15 +1,18 @@ package org.orcid.core.manager.v3.impl; +import org.orcid.core.manager.ProfileEntityCacheManager; import org.orcid.core.manager.v3.ProfileEmailDomainManager; import org.orcid.core.manager.v3.read_only.impl.ProfileEmailDomainManagerReadOnlyImpl; import org.orcid.jaxb.model.v3.release.common.Visibility; import org.orcid.persistence.dao.EmailDao; import org.orcid.persistence.dao.EmailDomainDao; +import org.orcid.persistence.dao.ProfileDao; import org.orcid.persistence.dao.ProfileEmailDomainDao; import org.orcid.persistence.jpa.entities.EmailDomainEntity; import org.orcid.persistence.jpa.entities.EmailEntity; import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity; +import org.orcid.persistence.jpa.entities.ProfileEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; @@ -34,7 +37,8 @@ public class ProfileEmailDomainManagerImpl extends ProfileEmailDomainManagerRead @Resource(name = "emailDaoReadOnly") protected EmailDao emailDaoReadOnly; - private static final String DEFAULT_DOMAIN_VISIBILITY = Visibility.PRIVATE.toString().toUpperCase(); + @Resource + private ProfileEntityCacheManager profileEntityCacheManager; @Transactional public void updateEmailDomains(String orcid, org.orcid.pojo.ajaxForm.Emails newEmails) { @@ -71,47 +75,16 @@ public void updateEmailDomains(String orcid, org.orcid.pojo.ajaxForm.Emails newE public void processDomain(String orcid, String email) { String domain = email.split("@")[1]; EmailDomainEntity domainInfo = emailDomainDao.findByEmailDomain(domain); - String domainVisibility = DEFAULT_DOMAIN_VISIBILITY; // Check if email is professional if (domainInfo != null && domainInfo.getCategory().equals(EmailDomainEntity.DomainCategory.PROFESSIONAL)) { ProfileEmailDomainEntity existingDomain = profileEmailDomainDao.findByEmailDomain(orcid, domain); // ADD NEW DOMAIN IF ONE DOESN'T EXIST if (existingDomain == null) { // Verify the user doesn't have more emails with that domain - List existingEmails = emailDaoReadOnly.findByOrcid(orcid, System.currentTimeMillis()); - if(existingEmails != null && existingEmails.size() > 1) { - for(EmailEntity emailEntity : existingEmails) { - //If it is not the same emails that is being verified and it is verified - if(!email.equals(emailEntity.getEmail()) && emailEntity.getVerified()) { - try { - String emailEntityDomain = (emailEntity.getEmail() == null) ? null : (email.split("@")[1]); - // If one of the existing emails have the same domain as the email being verified check the visibility and select the less restrictive - if(domain.equals(emailEntityDomain)){ - String entityVisibility = emailEntity.getVisibility(); - domainVisibility = getLessRestrictiveVisibility(domainVisibility, entityVisibility); - } - } catch (Exception e) { - LOGGER.warn("Could not get email domain from email entity " + emailEntity.getEmail(), e); - } - } - } - } + ProfileEntity profile = profileEntityCacheManager.retrieve(orcid); + String domainVisibility = profile.getActivitiesVisibilityDefault(); profileEmailDomainDao.addEmailDomain(orcid, domain, domainVisibility); } } } - - private String getLessRestrictiveVisibility(String a, String b) { - String visibility = DEFAULT_DOMAIN_VISIBILITY; - if(Visibility.PUBLIC.name().equals(a) || Visibility.PUBLIC.name().equals(b)) { - visibility = Visibility.PUBLIC.name(); - } else if(a.equals(b)) { - visibility = a; - } else if(Visibility.PRIVATE.name().equals(a)) { - visibility = b; - } else if(Visibility.PRIVATE.name().equals(b)) { - visibility = a; - } - return visibility; - } } From 85443c56e84d5d9470ef4bf4df2799a375e42dc2 Mon Sep 17 00:00:00 2001 From: github actions Date: Tue, 17 Sep 2024 17:28:47 +0000 Subject: [PATCH 13/36] v2.65.2 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a8aee8d89e..e1b92466bce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.65.2 - 2024-09-17 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.1...v2.65.2) + ## v2.65.1 - 2024-09-17 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.0...v2.65.1) From c8260d83e78974a7840c45bd359b48cbfa646ecf Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Tue, 17 Sep 2024 21:26:44 +0100 Subject: [PATCH 14/36] Keep just the ROR other names indexed in solr (#7087) Co-authored-by: Angel Montenegro --- .../core/manager/impl/OrgDisambiguatedManagerImpl.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java index 3a47eb28b31..18dea92a98c 100644 --- a/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/manager/impl/OrgDisambiguatedManagerImpl.java @@ -167,12 +167,6 @@ private OrgDisambiguatedSolrDocument convertEntityToDocument(OrgDisambiguatedEnt document.setOrgNamesJson(entity.getNamesJson()); } - List orgs = orgDao.findByOrgDisambiguatedId(entity.getId()); - if (orgs != null) { - for (OrgEntity org : orgs) { - orgNames.add(org.getName()); - } - } document.setOrgNames(new ArrayList<>(orgNames)); if (OrgDisambiguatedSourceType.FUNDREF.name().equals(entity.getSourceType())) { From 90b525f520cd62df8d2bd1c766c779f8abb1fc8f Mon Sep 17 00:00:00 2001 From: github actions Date: Tue, 17 Sep 2024 20:40:47 +0000 Subject: [PATCH 15/36] v2.65.3 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1b92466bce..7958c926896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.65.3 - 2024-09-17 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.2...v2.65.3) + ## v2.65.2 - 2024-09-17 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.1...v2.65.2) From 5c6fc01667a1e3cebe1004f8861f45baac0cdb8c Mon Sep 17 00:00:00 2001 From: github actions Date: Thu, 19 Sep 2024 20:11:28 +0000 Subject: [PATCH 16/36] v2.65.4 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7958c926896..323b9a3c05e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.65.4 - 2024-09-19 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.3...v2.65.4) + ## v2.65.3 - 2024-09-17 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.2...v2.65.3) From 4912303363cfc25506a437ca09a73482b3554d06 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Mon, 23 Sep 2024 22:22:22 +0100 Subject: [PATCH 17/36] Email domains fixes for summary endpoint (#7089) * Email domains fixes for summary endpoint * Fixes for summary unit test for marshalling --------- Co-authored-by: Angel Montenegro --- .../manager/impl/SummaryManagerImpl.java | 10 +++---- .../org/orcid/core/model/EmailDomain.java | 11 +++++--- .../pojo/summary/EmailDomainSummary.java | 26 ------------------- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java index 766f3f4f65a..3ecd48fb678 100644 --- a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java @@ -73,10 +73,11 @@ import org.orcid.pojo.summary.ExternalIdentifiersSummary; import org.orcid.pojo.summary.RecordSummaryPojo; import org.orcid.utils.DateUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; public class SummaryManagerImpl implements SummaryManager { - @Resource(name = "recordNameManagerReadOnlyV3") private RecordNameManagerReadOnly recordNameManagerReadOnly; @@ -285,8 +286,7 @@ public RecordSummaryPojo getRecordSummaryPojo(String orcid) { for (EmailDomain ed : recordSummary.getEmailDomains().getEmailDomains()) { EmailDomainSummary eds = new EmailDomainSummary(); eds.setValue(ed.getValue()); - eds.setCreatedDate(ed.getCreatedDate().toFuzzyDate().toString()); - eds.setLastModified(ed.getLastModified().toFuzzyDate().toString()); + emailDomains.add(eds); } } pojo.setEmailDomains(emailDomains); @@ -520,7 +520,6 @@ public void generateEmailDomainsSummary(RecordSummary recordSummary, String orci emailDomains = profileEmailDomainManagerReadOnly.getPublicEmailDomains(orcid); List edList = new ArrayList(); if (emailDomains != null && !emailDomains.isEmpty()) { - EmailDomain ed = null; for (ProfileEmailDomainEntity ped : emailDomains) { ed = new EmailDomain(); @@ -530,7 +529,6 @@ public void generateEmailDomainsSummary(RecordSummary recordSummary, String orci edList.add(ed); } } - List emailDomainsTop3 = new ArrayList(); edList.stream().limit(3).forEach(t -> { EmailDomain ed = new EmailDomain(); @@ -544,7 +542,9 @@ public void generateEmailDomainsSummary(RecordSummary recordSummary, String orci eds.setCount(edList.size()); if (!emailDomainsTop3.isEmpty()) { eds.setEmailDomains(emailDomainsTop3); + } + recordSummary.setEmailDomains(eds); } } diff --git a/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java b/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java index a31928c6841..779717dd90d 100644 --- a/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java +++ b/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java @@ -6,6 +6,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; import org.orcid.jaxb.model.v3.release.common.FuzzyDate; @@ -14,9 +15,9 @@ import io.swagger.v3.oas.annotations.media.Schema; @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(propOrder = { "value","createdDate", "lastModified"}) -@XmlRootElement(name = "education-qualification", namespace = "http://www.orcid.org/ns/summary") -@Schema(description = "Education Qualification") +@XmlType(propOrder = { "value", "createdDate","lastModified"}) +@XmlRootElement(name = "email-domain", namespace = "http://www.orcid.org/ns/summary") +@Schema(description = "Email Domain") public class EmailDomain { @XmlElement(name = "value", namespace = "http://www.orcid.org/ns/summary") protected String value; @@ -32,7 +33,8 @@ public String getValue() { public void setValue(String value) { this.value = value; } - + + @XmlTransient public Date getCreatedDate() { return createdDate; } @@ -41,6 +43,7 @@ public void setCreatedDate(Date createdDate) { this.createdDate = createdDate; } + @XmlTransient public Date getLastModified() { return lastModified; } diff --git a/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java b/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java index 4513d3db408..a8e6c1ba0a8 100644 --- a/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java +++ b/orcid-core/src/main/java/org/orcid/pojo/summary/EmailDomainSummary.java @@ -5,8 +5,6 @@ public class EmailDomainSummary { private String value; - private String createdDate; - private String lastModified; public String getValue() { return value; @@ -16,22 +14,6 @@ public void setValue(String value) { this.value = value; } - public String getCreatedDate() { - return createdDate; - } - - public void setCreatedDate(String createdDate) { - this.createdDate = createdDate; - } - - public String getLastModified() { - return lastModified; - } - - public void setLastModified(String lastModified) { - this.lastModified = lastModified; - } - public static EmailDomainSummary valueOf(ProfileEmailDomainEntity pem) { EmailDomainSummary form = new EmailDomainSummary(); @@ -40,14 +22,6 @@ public static EmailDomainSummary valueOf(ProfileEmailDomainEntity pem) { if(!PojoUtil.isEmpty(pem.getEmailDomain())) { form.setValue(pem.getEmailDomain()); } - - if (pem.getDateCreated() != null) { - form.setCreatedDate(org.orcid.pojo.ajaxForm.Date.valueOf(pem.getDateCreated()).toFuzzyDate().toString()); - } - - if (pem.getLastModified() !=null) { - form.setLastModified(org.orcid.pojo.ajaxForm.Date.valueOf(pem.getLastModified()).toFuzzyDate().toString()); - } } return form; } From d749f3a9ebd6173507dcfc98c6d1394b231605af Mon Sep 17 00:00:00 2001 From: github actions Date: Mon, 23 Sep 2024 21:36:15 +0000 Subject: [PATCH 18/36] v2.65.5 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 323b9a3c05e..2a2e9256221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.65.5 - 2024-09-23 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.4...v2.65.5) + ## v2.65.4 - 2024-09-19 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.3...v2.65.4) From f4fa943e0329141c64b263c85f80bd3a6f9af449 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru Date: Thu, 26 Sep 2024 13:55:13 +0100 Subject: [PATCH 19/36] Removed all created date, last modified from email domain summary --- .../manager/impl/SummaryManagerImpl.java | 4 --- .../org/orcid/core/model/EmailDomain.java | 27 +++---------------- .../model/RecordSummaryMarshallingTest.java | 4 +-- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java index 3ecd48fb678..3fcd322e53d 100644 --- a/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java +++ b/orcid-core/src/main/java/org/orcid/core/common/manager/impl/SummaryManagerImpl.java @@ -524,8 +524,6 @@ public void generateEmailDomainsSummary(RecordSummary recordSummary, String orci for (ProfileEmailDomainEntity ped : emailDomains) { ed = new EmailDomain(); ed.setValue(ped.getEmailDomain()); - ed.setCreatedDate(Date.valueOf(ped.getDateCreated())); - ed.setLastModified(Date.valueOf(ped.getLastModified())); edList.add(ed); } } @@ -533,8 +531,6 @@ public void generateEmailDomainsSummary(RecordSummary recordSummary, String orci edList.stream().limit(3).forEach(t -> { EmailDomain ed = new EmailDomain(); ed.setValue(t.getValue()); - ed.setCreatedDate(t.getCreatedDate()); - ed.setLastModified(t.getLastModified()); emailDomainsTop3.add(ed); }); diff --git a/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java b/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java index 779717dd90d..371b7948f04 100644 --- a/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java +++ b/orcid-core/src/main/java/org/orcid/core/model/EmailDomain.java @@ -15,16 +15,12 @@ import io.swagger.v3.oas.annotations.media.Schema; @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(propOrder = { "value", "createdDate","lastModified"}) +@XmlType(propOrder = { "value"}) @XmlRootElement(name = "email-domain", namespace = "http://www.orcid.org/ns/summary") @Schema(description = "Email Domain") public class EmailDomain { @XmlElement(name = "value", namespace = "http://www.orcid.org/ns/summary") protected String value; - @XmlElement(name = "created-date", namespace = "http://www.orcid.org/ns/common") - protected Date createdDate; - @XmlElement(name = "last-modified-date", namespace = "http://www.orcid.org/ns/common") - protected Date lastModified; public String getValue() { return value; @@ -34,27 +30,10 @@ public void setValue(String value) { this.value = value; } - @XmlTransient - public Date getCreatedDate() { - return createdDate; - } - - public void setCreatedDate(Date createdDate) { - this.createdDate = createdDate; - } - - @XmlTransient - public Date getLastModified() { - return lastModified; - } - - public void setLastModified(Date lastModified) { - this.lastModified = lastModified; - } @Override public int hashCode() { - return Objects.hash(value, createdDate, lastModified); + return Objects.hash(value); } @Override @@ -66,6 +45,6 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; EmailDomain other = (EmailDomain) obj; - return Objects.equals(createdDate, other.createdDate) && Objects.equals(lastModified, other.lastModified) && Objects.equals(value, other.value); + return Objects.equals(value, other.value); } } diff --git a/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java b/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java index 72c5a541aae..d55d341835b 100644 --- a/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java +++ b/orcid-core/src/test/java/org/orcid/core/model/RecordSummaryMarshallingTest.java @@ -97,7 +97,7 @@ private RecordSummary getRecordSummary() { EmailDomains emailDomains = new EmailDomains(); emailDomains.setCount(4); emailDomains.setEmailDomains(new ArrayList()); - emailDomains.getEmailDomains().add(getEmailDomain("sometrusted.org", getEmailDomainCreatedDate(), getEmailDomainLastModified())); + emailDomains.getEmailDomains().add(getEmailDomain("sometrusted.org")); record.setEmailDomains(emailDomains); //Set education/qualifications @@ -163,7 +163,7 @@ private EducationQualification getEducationQualification(int putCode, String rol return eq; } - private EmailDomain getEmailDomain(String domainValue, Date created, Date modified) { + private EmailDomain getEmailDomain(String domainValue) { EmailDomain emailDomain = new EmailDomain(); emailDomain.setValue(domainValue); //emailDomain.setCreatedDate(created); From a9da77d247f4bf874d38efe6c856cd342a3c1e9c Mon Sep 17 00:00:00 2001 From: Camelia Dumitru Date: Fri, 27 Sep 2024 15:32:14 +0100 Subject: [PATCH 20/36] Added the code to store deleted items in panoply dw_deleted_items table The items will be processed by the script that runs daily and cleaned up after the item is deleted from the corresponding view --- .../impl/OrgAffiliationRelationDaoImpl.java | 66 ++++++++++++++++++- .../resources/orcid-persistence-context.xml | 16 +++++ orcid-utils/pom.xml | 20 ++++++ .../utils/panoply/PanoplyDeletedItem.java | 55 ++++++++++++++++ .../utils/panoply/PanoplyRedshiftClient.java | 36 ++++++++++ properties/development.properties | 12 +++- 6 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java create mode 100644 orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java index 51185a67132..de1c3a5bf1f 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java @@ -3,19 +3,32 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Resource; import javax.persistence.Query; import javax.persistence.TypedQuery; +import org.orcid.utils.panoply.PanoplyDeletedItem; +import org.orcid.utils.panoply.PanoplyRedshiftClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.commons.logging.Log; import org.orcid.persistence.aop.UpdateProfileLastModified; import org.orcid.persistence.aop.UpdateProfileLastModifiedAndIndexingStatus; import org.orcid.persistence.dao.OrgAffiliationRelationDao; import org.orcid.persistence.jpa.entities.OrgAffiliationRelationEntity; +import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.transaction.annotation.Transactional; public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl implements OrgAffiliationRelationDao { - + + private static final Logger LOG = LoggerFactory.getLogger(OrgAffiliationRelationDaoImpl.class); + + @Value("${org.orcid.persistence.panoply.cleanup.production:false}") + private boolean enablePanoplyCleanupInProduction; + private static final String AFFILIATION_TYPE_DISTINCTION = "DISTINCTION"; private static final String AFFILIATION_TYPE_EDUCATION = "EDUCATION"; @@ -29,6 +42,11 @@ public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl 0 ? true : false; + if(query.executeUpdate() > 0) { + if(enablePanoplyCleanupInProduction) { + PanoplyDeletedItem item = new PanoplyDeletedItem(); + item.setItemId(orgAffiliationRelationId); + item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); + storeDeletedItemInPanoply(item); + } + return true; + } + return false; + } + + private void storeDeletedItemInPanoply(PanoplyDeletedItem item) { + //Store the deleted item in panoply Db without blocking + CompletableFuture.supplyAsync(() -> { + try { + panoplyClient.addPanoplyDeletedItem(item); + return true; + } catch (Exception e) { + LOG.error("Cannot store deleted affiliation in panoply ", e); + return false; + } + }).thenAccept(result -> { + if(! result) { + LOG.error("Async call to panoply for : " + item.toString() + " Stored: "+ result); + } + + }); } /** @@ -196,6 +241,14 @@ public void removeOrgAffiliationByClientSourceId(String clientSourceId) { Query query = entityManager.createNativeQuery("DELETE FROM org_affiliation_relation WHERE client_source_id=:clientSourceId"); query.setParameter("clientSourceId", clientSourceId); query.executeUpdate(); + if(query.executeUpdate() > 0) { + if(enablePanoplyCleanupInProduction) { + PanoplyDeletedItem item = new PanoplyDeletedItem(); + item.setClientSourceId(clientSourceId); + item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); + storeDeletedItemInPanoply(item); + } + } } @Override @@ -281,6 +334,15 @@ public void removeAllAffiliations(String orcid) { Query query = entityManager.createQuery("delete from OrgAffiliationRelationEntity where orcid = :orcid"); query.setParameter("orcid", orcid); query.executeUpdate(); + if(query.executeUpdate() > 0) { + if(enablePanoplyCleanupInProduction) { + PanoplyDeletedItem item = new PanoplyDeletedItem(); + item.setOrcid(orcid); + item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); + storeDeletedItemInPanoply(item); + } + } + } @Override diff --git a/orcid-persistence/src/main/resources/orcid-persistence-context.xml b/orcid-persistence/src/main/resources/orcid-persistence-context.xml index d57dde50df1..7857fb72b54 100644 --- a/orcid-persistence/src/main/resources/orcid-persistence-context.xml +++ b/orcid-persistence/src/main/resources/orcid-persistence-context.xml @@ -457,6 +457,22 @@ + + + + + + + + + + + + + + + + diff --git a/orcid-utils/pom.xml b/orcid-utils/pom.xml index d7b361ba22d..6ee5bc45646 100644 --- a/orcid-utils/pom.xml +++ b/orcid-utils/pom.xml @@ -43,6 +43,10 @@ org.springframework spring-context + + org.springframework + spring-jdbc + org.apache.commons commons-lang3 @@ -113,6 +117,22 @@ jsoup 1.15.4 + + + + com.amazon.redshift + redshift-jdbc42 + 2.1.0.30 + + + + + + com.zaxxer + HikariCP + 5.0.1 + + diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java new file mode 100644 index 00000000000..378b0185227 --- /dev/null +++ b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java @@ -0,0 +1,55 @@ +package org.orcid.utils.panoply; + +public class PanoplyDeletedItem { + private Long id; + private String dwTable; + private Long itemId; + private String clientSourceId; + private String orcid; + + public final String DW_ORG_AFFILIATION_RELATION = "dw_org_affiliation_relation"; + public final String DW_WORK = "dw_work"; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getDwTable() { + return dwTable; + } + public void setDwTable(String dwTable) { + this.dwTable = dwTable; + } + public Long getItemId() { + return itemId; + } + public void setItemId(Long itemId) { + this.itemId = itemId; + } + public String getClientSourceId() { + return clientSourceId; + } + public void setClientSourceId(String clientSourceId) { + this.clientSourceId = clientSourceId; + } + public String getOrcid() { + return orcid; + } + public void setOrcid(String orcid) { + this.orcid = orcid; + } + + @Override + public String toString() { + return "PanoplyDeletedItem{" + + "id=" + id + + ", dwTable='" + dwTable + '\'' + + ", itemId='" + itemId + '\'' + + ", clientSourceId='" + clientSourceId + '\'' + + ", orcid='" + orcid + '\'' + + '}'; + } + +} diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java new file mode 100644 index 00000000000..3499593eb27 --- /dev/null +++ b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java @@ -0,0 +1,36 @@ +package org.orcid.utils.panoply; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.stereotype.Service; + + +import java.util.Date; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.orcid.utils.alerting.SlackManager; + +@Repository +public class PanoplyRedshiftClient { + + private static final Logger LOG = LoggerFactory.getLogger(PanoplyRedshiftClient.class); + + @Autowired + @Qualifier("panoplyJdbcTemplate") + private JdbcTemplate panoplyJdbcTemplate; + + + public int addPanoplyDeletedItem(PanoplyDeletedItem item) { + LOG.debug("Adding deleted item to panoply DB: " + item.toString()); + String sql = "INSERT INTO dw_deleted_items (item_id, orcid, client_source_id, date_deleted, dw_table) VALUES (?, ?, ?, ?, ?)"; + return panoplyJdbcTemplate.update(sql, item.getItemId(), item.getOrcid(), item.getClientSourceId(), new java.sql.Timestamp(new Date().getTime()), item.getDwTable()); + } + +} diff --git a/properties/development.properties b/properties/development.properties index 34eae804933..9186b22ceb8 100644 --- a/properties/development.properties +++ b/properties/development.properties @@ -258,5 +258,15 @@ org.orcid.scheduler.autospam.enabled=true org.orcid.core.autospam.slackChannel=collab-spam-reports org.orcid.core.autospam.webhookUrl= -#org.orcid.persistence.liquibase.enabled=false +org.orcid.persistence.liquibase.enabled=false org.orcid.persistence.solr.read.only.url=http://localhost:8983/solr + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx From 6fdf65e6418bf3835b239893ee6965c156b4758a Mon Sep 17 00:00:00 2001 From: leomendoza123 Date: Tue, 1 Oct 2024 21:24:34 -0600 Subject: [PATCH 21/36] Revert "Added the code to store deleted items in panoply dw_deleted_items table" --- .../impl/OrgAffiliationRelationDaoImpl.java | 66 +------------------ .../resources/orcid-persistence-context.xml | 16 ----- orcid-utils/pom.xml | 20 ------ .../utils/panoply/PanoplyDeletedItem.java | 55 ---------------- .../utils/panoply/PanoplyRedshiftClient.java | 36 ---------- properties/development.properties | 12 +--- 6 files changed, 3 insertions(+), 202 deletions(-) delete mode 100644 orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java delete mode 100644 orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java index de1c3a5bf1f..51185a67132 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java @@ -3,32 +3,19 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CompletableFuture; -import javax.annotation.Resource; import javax.persistence.Query; import javax.persistence.TypedQuery; -import org.orcid.utils.panoply.PanoplyDeletedItem; -import org.orcid.utils.panoply.PanoplyRedshiftClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.commons.logging.Log; import org.orcid.persistence.aop.UpdateProfileLastModified; import org.orcid.persistence.aop.UpdateProfileLastModifiedAndIndexingStatus; import org.orcid.persistence.dao.OrgAffiliationRelationDao; import org.orcid.persistence.jpa.entities.OrgAffiliationRelationEntity; -import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.transaction.annotation.Transactional; public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl implements OrgAffiliationRelationDao { - - private static final Logger LOG = LoggerFactory.getLogger(OrgAffiliationRelationDaoImpl.class); - - @Value("${org.orcid.persistence.panoply.cleanup.production:false}") - private boolean enablePanoplyCleanupInProduction; - + private static final String AFFILIATION_TYPE_DISTINCTION = "DISTINCTION"; private static final String AFFILIATION_TYPE_EDUCATION = "EDUCATION"; @@ -42,11 +29,6 @@ public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl 0) { - if(enablePanoplyCleanupInProduction) { - PanoplyDeletedItem item = new PanoplyDeletedItem(); - item.setItemId(orgAffiliationRelationId); - item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); - storeDeletedItemInPanoply(item); - } - return true; - } - return false; - } - - private void storeDeletedItemInPanoply(PanoplyDeletedItem item) { - //Store the deleted item in panoply Db without blocking - CompletableFuture.supplyAsync(() -> { - try { - panoplyClient.addPanoplyDeletedItem(item); - return true; - } catch (Exception e) { - LOG.error("Cannot store deleted affiliation in panoply ", e); - return false; - } - }).thenAccept(result -> { - if(! result) { - LOG.error("Async call to panoply for : " + item.toString() + " Stored: "+ result); - } - - }); + return query.executeUpdate() > 0 ? true : false; } /** @@ -241,14 +196,6 @@ public void removeOrgAffiliationByClientSourceId(String clientSourceId) { Query query = entityManager.createNativeQuery("DELETE FROM org_affiliation_relation WHERE client_source_id=:clientSourceId"); query.setParameter("clientSourceId", clientSourceId); query.executeUpdate(); - if(query.executeUpdate() > 0) { - if(enablePanoplyCleanupInProduction) { - PanoplyDeletedItem item = new PanoplyDeletedItem(); - item.setClientSourceId(clientSourceId); - item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); - storeDeletedItemInPanoply(item); - } - } } @Override @@ -334,15 +281,6 @@ public void removeAllAffiliations(String orcid) { Query query = entityManager.createQuery("delete from OrgAffiliationRelationEntity where orcid = :orcid"); query.setParameter("orcid", orcid); query.executeUpdate(); - if(query.executeUpdate() > 0) { - if(enablePanoplyCleanupInProduction) { - PanoplyDeletedItem item = new PanoplyDeletedItem(); - item.setOrcid(orcid); - item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); - storeDeletedItemInPanoply(item); - } - } - } @Override diff --git a/orcid-persistence/src/main/resources/orcid-persistence-context.xml b/orcid-persistence/src/main/resources/orcid-persistence-context.xml index 7857fb72b54..d57dde50df1 100644 --- a/orcid-persistence/src/main/resources/orcid-persistence-context.xml +++ b/orcid-persistence/src/main/resources/orcid-persistence-context.xml @@ -457,22 +457,6 @@ - - - - - - - - - - - - - - - - diff --git a/orcid-utils/pom.xml b/orcid-utils/pom.xml index 6ee5bc45646..d7b361ba22d 100644 --- a/orcid-utils/pom.xml +++ b/orcid-utils/pom.xml @@ -43,10 +43,6 @@ org.springframework spring-context - - org.springframework - spring-jdbc - org.apache.commons commons-lang3 @@ -117,22 +113,6 @@ jsoup 1.15.4 - - - - com.amazon.redshift - redshift-jdbc42 - 2.1.0.30 - - - - - - com.zaxxer - HikariCP - 5.0.1 - - diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java deleted file mode 100644 index 378b0185227..00000000000 --- a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.orcid.utils.panoply; - -public class PanoplyDeletedItem { - private Long id; - private String dwTable; - private Long itemId; - private String clientSourceId; - private String orcid; - - public final String DW_ORG_AFFILIATION_RELATION = "dw_org_affiliation_relation"; - public final String DW_WORK = "dw_work"; - - public Long getId() { - return id; - } - public void setId(Long id) { - this.id = id; - } - public String getDwTable() { - return dwTable; - } - public void setDwTable(String dwTable) { - this.dwTable = dwTable; - } - public Long getItemId() { - return itemId; - } - public void setItemId(Long itemId) { - this.itemId = itemId; - } - public String getClientSourceId() { - return clientSourceId; - } - public void setClientSourceId(String clientSourceId) { - this.clientSourceId = clientSourceId; - } - public String getOrcid() { - return orcid; - } - public void setOrcid(String orcid) { - this.orcid = orcid; - } - - @Override - public String toString() { - return "PanoplyDeletedItem{" + - "id=" + id + - ", dwTable='" + dwTable + '\'' + - ", itemId='" + itemId + '\'' + - ", clientSourceId='" + clientSourceId + '\'' + - ", orcid='" + orcid + '\'' + - '}'; - } - -} diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java deleted file mode 100644 index 3499593eb27..00000000000 --- a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.orcid.utils.panoply; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.stereotype.Repository; -import org.springframework.stereotype.Service; - - -import java.util.Date; - -import javax.annotation.Resource; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.orcid.utils.alerting.SlackManager; - -@Repository -public class PanoplyRedshiftClient { - - private static final Logger LOG = LoggerFactory.getLogger(PanoplyRedshiftClient.class); - - @Autowired - @Qualifier("panoplyJdbcTemplate") - private JdbcTemplate panoplyJdbcTemplate; - - - public int addPanoplyDeletedItem(PanoplyDeletedItem item) { - LOG.debug("Adding deleted item to panoply DB: " + item.toString()); - String sql = "INSERT INTO dw_deleted_items (item_id, orcid, client_source_id, date_deleted, dw_table) VALUES (?, ?, ?, ?, ?)"; - return panoplyJdbcTemplate.update(sql, item.getItemId(), item.getOrcid(), item.getClientSourceId(), new java.sql.Timestamp(new Date().getTime()), item.getDwTable()); - } - -} diff --git a/properties/development.properties b/properties/development.properties index 9186b22ceb8..34eae804933 100644 --- a/properties/development.properties +++ b/properties/development.properties @@ -258,15 +258,5 @@ org.orcid.scheduler.autospam.enabled=true org.orcid.core.autospam.slackChannel=collab-spam-reports org.orcid.core.autospam.webhookUrl= -org.orcid.persistence.liquibase.enabled=false +#org.orcid.persistence.liquibase.enabled=false org.orcid.persistence.solr.read.only.url=http://localhost:8983/solr - -org.orcid.persistence.panoply.cleanup.production=false -# Panoply redshift database -org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver -org.orcid.core.utils.panoply.maxPoolSize=20 -org.orcid.core.utils.panoply.password=xxx -org.orcid.core.utils.panoply.idleConnectionTimeout=3600 -org.orcid.core.utils.panoply.connectionTimeout=36000 -org.orcid.core.utils.panoply.jdbcUrl=xxx -org.orcid.core.utils.panoply.username=xxx From ccf173061d0655799103a99189a771c204e3ddf5 Mon Sep 17 00:00:00 2001 From: github actions Date: Wed, 2 Oct 2024 03:47:10 +0000 Subject: [PATCH 22/36] v2.65.6 changelog update --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a2e9256221..0e40966486f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v2.65.6 - 2024-10-02 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.5...v2.65.6) + +- [#7093](https://github.com/ORCID/ORCID-Source/pull/7093): Revert "Added the code to store deleted items in panoply dw_deleted_items table" +- [#7091](https://github.com/ORCID/ORCID-Source/pull/7091): Added the code to store deleted items in panoply dw_deleted_items table +- [#7090](https://github.com/ORCID/ORCID-Source/pull/7090): Removed all created date, last modified from email domain summary + ## v2.65.5 - 2024-09-23 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.4...v2.65.5) From 39aad67c37cbd236904fca61dc9d11e580f26cee Mon Sep 17 00:00:00 2001 From: Giles Westwood Date: Mon, 7 Oct 2024 15:32:01 +0100 Subject: [PATCH 23/36] feat: map check names to their workflow files to allow for searching --- .github/workflows/maven_test_publish.yml | 2 +- .github/workflows/maven_test_report.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven_test_publish.yml b/.github/workflows/maven_test_publish.yml index 995ed7b7d00..33a6c1132d6 100644 --- a/.github/workflows/maven_test_publish.yml +++ b/.github/workflows/maven_test_publish.yml @@ -165,7 +165,7 @@ jobs: uses: dorny/test-reporter@e9fa2f582c0ebbe2e263fd18fad744d52e0b0203 if: always() with: - name: "${{ inputs.project }}: Unit tests results" + name: "maven_test_publish_${{ inputs.project }}" path: ${{ inputs.project }}/target/surefire-reports/*.xml reporter: java-junit fail-on-error: true diff --git a/.github/workflows/maven_test_report.yml b/.github/workflows/maven_test_report.yml index 017fe9c7af9..e44b1f70c99 100644 --- a/.github/workflows/maven_test_report.yml +++ b/.github/workflows/maven_test_report.yml @@ -24,7 +24,7 @@ jobs: - uses: dorny/test-reporter@e9fa2f582c0ebbe2e263fd18fad744d52e0b0203 with: artifact: ${{ inputs.project }} - name: "${{ inputs.project }} Unit Tests" # Name of the check run which will be created + name: "maven_test_report_${{ inputs.project }}" # Name of the check run which will be created path: '*.xml' # Path to test results (inside artifact .zip) reporter: java-junit # Format of test results From 3b7017caeb2265472c6b40c805b5d47f2f86512a Mon Sep 17 00:00:00 2001 From: github actions Date: Wed, 9 Oct 2024 13:18:48 +0000 Subject: [PATCH 24/36] v2.66.0 changelog update --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e40966486f..95e0bc328ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v2.66.0 - 2024-10-09 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.6...v2.66.0) + +### Feature + +- map check names to their workflow files to allow for searching + ## v2.65.6 - 2024-10-02 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.5...v2.65.6) From bb4e1010bfdcadc1d5e261ac6e416a24a66a9427 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:49:06 +0100 Subject: [PATCH 25/36] Added the date verified when verifying an email address (#7101) Co-authored-by: Angel Montenegro --- .../orcid/persistence/dao/impl/EmailDaoImpl.java | 2 +- .../persistence/jpa/entities/EmailEntity.java | 14 +++++++++++++- orcid-persistence/src/main/resources/db-master.xml | 1 + .../db/updates/add_date_verified_to_email.xml | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/EmailDaoImpl.java b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/EmailDaoImpl.java index a0effb50ab8..3df5afeb243 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/EmailDaoImpl.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/EmailDaoImpl.java @@ -123,7 +123,7 @@ public void addSourceToEmail(String sourceId, String email) { @Transactional @UpdateProfileLastModified public boolean verifyEmail(String email) { - Query query = entityManager.createNativeQuery("update email set is_verified = true, is_current=true, last_modified=now() where trim(lower(email)) = trim(lower(:email))"); + Query query = entityManager.createNativeQuery("update email set is_verified = true, is_current=true, last_modified=now(), date_verified=now() where trim(lower(email)) = trim(lower(:email))"); query.setParameter("email", email); return query.executeUpdate() > 0; } diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/EmailEntity.java b/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/EmailEntity.java index d9dbd1b5a8e..6977ec86502 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/EmailEntity.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/jpa/entities/EmailEntity.java @@ -3,6 +3,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; @@ -24,7 +25,8 @@ public class EmailEntity extends SourceAwareEntity implements OrcidAware private Boolean primary; private Boolean current; private Boolean verified; - private String visibility; + private String visibility; + private Date dateVerified; @Override @Id @@ -90,6 +92,15 @@ public String getVisibility() { public void setVisibility(String visibility) { this.visibility = visibility; } + + @Column(name = "date_verified") + public Date getDateVerified() { + return dateVerified; + } + + public void setDateVerified(Date dateVerified) { + this.dateVerified = dateVerified; + } public static Map mapByLowerCaseEmail(Collection emailEntities) { Map map = new HashMap<>(); @@ -109,5 +120,6 @@ public void clean() { visibility= null; verified = null; visibility = null; + dateVerified = null; } } \ No newline at end of file diff --git a/orcid-persistence/src/main/resources/db-master.xml b/orcid-persistence/src/main/resources/db-master.xml index c1a531b9bb3..65dfe060bf5 100644 --- a/orcid-persistence/src/main/resources/db-master.xml +++ b/orcid-persistence/src/main/resources/db-master.xml @@ -404,4 +404,5 @@ + \ No newline at end of file diff --git a/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml b/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml new file mode 100644 index 00000000000..2b1327cf016 --- /dev/null +++ b/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file From 7ab48afeed59201ebbf7fcf0e5576cd2dd596c9d Mon Sep 17 00:00:00 2001 From: github actions Date: Wed, 9 Oct 2024 18:03:48 +0000 Subject: [PATCH 26/36] v2.66.1 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95e0bc328ff..c427584637c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.66.1 - 2024-10-09 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.0...v2.66.1) + ## v2.66.0 - 2024-10-09 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.65.6...v2.66.0) From 68efbf6864b89f7911de272f3c24a8b4bade5728 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:43:00 +0100 Subject: [PATCH 27/36] Changed the type from timestamp to timestamp with timezone for date verified (#7102) --- .../main/resources/db/updates/add_date_verified_to_email.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml b/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml index 2b1327cf016..474039fe4e2 100644 --- a/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml +++ b/orcid-persistence/src/main/resources/db/updates/add_date_verified_to_email.xml @@ -6,7 +6,7 @@ - + From 2be37019e365ec95b1e1e63310d41c903b00c0f7 Mon Sep 17 00:00:00 2001 From: github actions Date: Thu, 10 Oct 2024 14:59:33 +0000 Subject: [PATCH 28/36] v2.66.2 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c427584637c..de70c422689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.66.2 - 2024-10-10 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.1...v2.66.2) + ## v2.66.1 - 2024-10-09 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.0...v2.66.1) From 6a075350a864a47ee12a1f540f246644ed1e9957 Mon Sep 17 00:00:00 2001 From: Angel Montenegro Date: Fri, 11 Oct 2024 12:08:54 -0600 Subject: [PATCH 29/36] Revert "Revert "Added the code to store deleted items in panoply dw_deleted_items table"" (#7100) * Revert "Revert "Added the code to store deleted items in panoply dw_deleted_items table"" * Fixed the failures in test suite --------- Co-authored-by: Camelia Dumitru --- .../impl/OrgAffiliationRelationDaoImpl.java | 66 ++++++++++++++++++- .../resources/orcid-persistence-context.xml | 21 +++++- .../properties/test-api-common.properties | 14 +++- .../properties/test-api-internal.properties | 14 +++- .../resources/properties/test-core.properties | 14 +++- .../resources/properties/test-db.properties | 12 ++++ .../properties/test-scheduler.properties | 12 ++++ .../resources/properties/test-ui.properties | 14 +++- orcid-utils/pom.xml | 20 ++++++ .../utils/panoply/PanoplyDeletedItem.java | 55 ++++++++++++++++ .../utils/panoply/PanoplyRedshiftClient.java | 36 ++++++++++ properties/development.properties | 12 +++- 12 files changed, 282 insertions(+), 8 deletions(-) create mode 100644 orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java create mode 100644 orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java index 51185a67132..de1c3a5bf1f 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java @@ -3,19 +3,32 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; +import javax.annotation.Resource; import javax.persistence.Query; import javax.persistence.TypedQuery; +import org.orcid.utils.panoply.PanoplyDeletedItem; +import org.orcid.utils.panoply.PanoplyRedshiftClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.commons.logging.Log; import org.orcid.persistence.aop.UpdateProfileLastModified; import org.orcid.persistence.aop.UpdateProfileLastModifiedAndIndexingStatus; import org.orcid.persistence.dao.OrgAffiliationRelationDao; import org.orcid.persistence.jpa.entities.OrgAffiliationRelationEntity; +import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.transaction.annotation.Transactional; public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl implements OrgAffiliationRelationDao { - + + private static final Logger LOG = LoggerFactory.getLogger(OrgAffiliationRelationDaoImpl.class); + + @Value("${org.orcid.persistence.panoply.cleanup.production:false}") + private boolean enablePanoplyCleanupInProduction; + private static final String AFFILIATION_TYPE_DISTINCTION = "DISTINCTION"; private static final String AFFILIATION_TYPE_EDUCATION = "EDUCATION"; @@ -29,6 +42,11 @@ public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl 0 ? true : false; + if(query.executeUpdate() > 0) { + if(enablePanoplyCleanupInProduction) { + PanoplyDeletedItem item = new PanoplyDeletedItem(); + item.setItemId(orgAffiliationRelationId); + item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); + storeDeletedItemInPanoply(item); + } + return true; + } + return false; + } + + private void storeDeletedItemInPanoply(PanoplyDeletedItem item) { + //Store the deleted item in panoply Db without blocking + CompletableFuture.supplyAsync(() -> { + try { + panoplyClient.addPanoplyDeletedItem(item); + return true; + } catch (Exception e) { + LOG.error("Cannot store deleted affiliation in panoply ", e); + return false; + } + }).thenAccept(result -> { + if(! result) { + LOG.error("Async call to panoply for : " + item.toString() + " Stored: "+ result); + } + + }); } /** @@ -196,6 +241,14 @@ public void removeOrgAffiliationByClientSourceId(String clientSourceId) { Query query = entityManager.createNativeQuery("DELETE FROM org_affiliation_relation WHERE client_source_id=:clientSourceId"); query.setParameter("clientSourceId", clientSourceId); query.executeUpdate(); + if(query.executeUpdate() > 0) { + if(enablePanoplyCleanupInProduction) { + PanoplyDeletedItem item = new PanoplyDeletedItem(); + item.setClientSourceId(clientSourceId); + item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); + storeDeletedItemInPanoply(item); + } + } } @Override @@ -281,6 +334,15 @@ public void removeAllAffiliations(String orcid) { Query query = entityManager.createQuery("delete from OrgAffiliationRelationEntity where orcid = :orcid"); query.setParameter("orcid", orcid); query.executeUpdate(); + if(query.executeUpdate() > 0) { + if(enablePanoplyCleanupInProduction) { + PanoplyDeletedItem item = new PanoplyDeletedItem(); + item.setOrcid(orcid); + item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); + storeDeletedItemInPanoply(item); + } + } + } @Override diff --git a/orcid-persistence/src/main/resources/orcid-persistence-context.xml b/orcid-persistence/src/main/resources/orcid-persistence-context.xml index d57dde50df1..554d47b39a6 100644 --- a/orcid-persistence/src/main/resources/orcid-persistence-context.xml +++ b/orcid-persistence/src/main/resources/orcid-persistence-context.xml @@ -457,10 +457,29 @@ + + + + + + + + + + + + + + + + - + + + + diff --git a/orcid-test/src/main/resources/properties/test-api-common.properties b/orcid-test/src/main/resources/properties/test-api-common.properties index 537759cfde2..dc4889fc41d 100644 --- a/orcid-test/src/main/resources/properties/test-api-common.properties +++ b/orcid-test/src/main/resources/properties/test-api-common.properties @@ -9,4 +9,16 @@ org.orcid.swagger.authendpoint=https://localhost:8443/orcid-web/oauth/authorize # Redis org.orcid.core.utils.cache.redis.host=xxx.xxx.com org.orcid.core.utils.cache.redis.port=6379 -org.orcid.core.utils.cache.redis.password=XXXX \ No newline at end of file +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx \ No newline at end of file diff --git a/orcid-test/src/main/resources/properties/test-api-internal.properties b/orcid-test/src/main/resources/properties/test-api-internal.properties index d85df6f3aba..284325b6265 100644 --- a/orcid-test/src/main/resources/properties/test-api-internal.properties +++ b/orcid-test/src/main/resources/properties/test-api-internal.properties @@ -9,4 +9,16 @@ org.orcid.persistence.internal_api.db.readonly.maxPoolSize=3 # Redis org.orcid.core.utils.cache.redis.host=xxx.xxx.com org.orcid.core.utils.cache.redis.port=6379 -org.orcid.core.utils.cache.redis.password=XXXX \ No newline at end of file +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx \ No newline at end of file diff --git a/orcid-test/src/main/resources/properties/test-core.properties b/orcid-test/src/main/resources/properties/test-core.properties index ab3c0577d4c..1dc1d3e9298 100644 --- a/orcid-test/src/main/resources/properties/test-core.properties +++ b/orcid-test/src/main/resources/properties/test-core.properties @@ -76,4 +76,16 @@ org.orcid.core.orgsToGroup.query=select a.* from org_disambiguated a full outer # Redis org.orcid.core.utils.cache.redis.host=xxx.xxx.com org.orcid.core.utils.cache.redis.port=6379 -org.orcid.core.utils.cache.redis.password=XXXX \ No newline at end of file +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx \ No newline at end of file diff --git a/orcid-test/src/main/resources/properties/test-db.properties b/orcid-test/src/main/resources/properties/test-db.properties index 8f8e05d0d68..a2c679f182a 100644 --- a/orcid-test/src/main/resources/properties/test-db.properties +++ b/orcid-test/src/main/resources/properties/test-db.properties @@ -46,3 +46,15 @@ org.orcid.persistence.togglz.db.testConnectionOnCheckin=true org.orcid.persistence.togglz.db.preferredTestQuery=select 1 org.orcid.persistence.togglz.db.numHelperThreads=5 org.orcid.persistence.togglz.cache.ttl=60000 + +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx diff --git a/orcid-test/src/main/resources/properties/test-scheduler.properties b/orcid-test/src/main/resources/properties/test-scheduler.properties index 10d29640a51..f1d06636692 100644 --- a/orcid-test/src/main/resources/properties/test-scheduler.properties +++ b/orcid-test/src/main/resources/properties/test-scheduler.properties @@ -42,3 +42,15 @@ org.orcid.core.orgs.ror.localZipPath=/tmp/ror/ror.zip org.orcid.core.utils.cache.redis.host=xxx.xxx.com org.orcid.core.utils.cache.redis.port=6379 org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx diff --git a/orcid-test/src/main/resources/properties/test-ui.properties b/orcid-test/src/main/resources/properties/test-ui.properties index 6784fbe3068..9741a3fc49b 100644 --- a/orcid-test/src/main/resources/properties/test-ui.properties +++ b/orcid-test/src/main/resources/properties/test-ui.properties @@ -28,4 +28,16 @@ org.orcid.core.profile.lockout.threshhold=10 # Redis org.orcid.core.utils.cache.redis.host=xxx.xxx.com org.orcid.core.utils.cache.redis.port=6379 -org.orcid.core.utils.cache.redis.password=XXXX \ No newline at end of file +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.core.utils.cache.redis.password=XXXX + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx \ No newline at end of file diff --git a/orcid-utils/pom.xml b/orcid-utils/pom.xml index d7b361ba22d..6ee5bc45646 100644 --- a/orcid-utils/pom.xml +++ b/orcid-utils/pom.xml @@ -43,6 +43,10 @@ org.springframework spring-context + + org.springframework + spring-jdbc + org.apache.commons commons-lang3 @@ -113,6 +117,22 @@ jsoup 1.15.4 + + + + com.amazon.redshift + redshift-jdbc42 + 2.1.0.30 + + + + + + com.zaxxer + HikariCP + 5.0.1 + + diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java new file mode 100644 index 00000000000..378b0185227 --- /dev/null +++ b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java @@ -0,0 +1,55 @@ +package org.orcid.utils.panoply; + +public class PanoplyDeletedItem { + private Long id; + private String dwTable; + private Long itemId; + private String clientSourceId; + private String orcid; + + public final String DW_ORG_AFFILIATION_RELATION = "dw_org_affiliation_relation"; + public final String DW_WORK = "dw_work"; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getDwTable() { + return dwTable; + } + public void setDwTable(String dwTable) { + this.dwTable = dwTable; + } + public Long getItemId() { + return itemId; + } + public void setItemId(Long itemId) { + this.itemId = itemId; + } + public String getClientSourceId() { + return clientSourceId; + } + public void setClientSourceId(String clientSourceId) { + this.clientSourceId = clientSourceId; + } + public String getOrcid() { + return orcid; + } + public void setOrcid(String orcid) { + this.orcid = orcid; + } + + @Override + public String toString() { + return "PanoplyDeletedItem{" + + "id=" + id + + ", dwTable='" + dwTable + '\'' + + ", itemId='" + itemId + '\'' + + ", clientSourceId='" + clientSourceId + '\'' + + ", orcid='" + orcid + '\'' + + '}'; + } + +} diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java new file mode 100644 index 00000000000..3499593eb27 --- /dev/null +++ b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java @@ -0,0 +1,36 @@ +package org.orcid.utils.panoply; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; +import org.springframework.stereotype.Service; + + +import java.util.Date; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.orcid.utils.alerting.SlackManager; + +@Repository +public class PanoplyRedshiftClient { + + private static final Logger LOG = LoggerFactory.getLogger(PanoplyRedshiftClient.class); + + @Autowired + @Qualifier("panoplyJdbcTemplate") + private JdbcTemplate panoplyJdbcTemplate; + + + public int addPanoplyDeletedItem(PanoplyDeletedItem item) { + LOG.debug("Adding deleted item to panoply DB: " + item.toString()); + String sql = "INSERT INTO dw_deleted_items (item_id, orcid, client_source_id, date_deleted, dw_table) VALUES (?, ?, ?, ?, ?)"; + return panoplyJdbcTemplate.update(sql, item.getItemId(), item.getOrcid(), item.getClientSourceId(), new java.sql.Timestamp(new Date().getTime()), item.getDwTable()); + } + +} diff --git a/properties/development.properties b/properties/development.properties index 34eae804933..9186b22ceb8 100644 --- a/properties/development.properties +++ b/properties/development.properties @@ -258,5 +258,15 @@ org.orcid.scheduler.autospam.enabled=true org.orcid.core.autospam.slackChannel=collab-spam-reports org.orcid.core.autospam.webhookUrl= -#org.orcid.persistence.liquibase.enabled=false +org.orcid.persistence.liquibase.enabled=false org.orcid.persistence.solr.read.only.url=http://localhost:8983/solr + +org.orcid.persistence.panoply.cleanup.production=false +# Panoply redshift database +org.orcid.core.utils.panoply.driver=com.amazon.redshift.jdbc.Driver +org.orcid.core.utils.panoply.maxPoolSize=20 +org.orcid.core.utils.panoply.password=xxx +org.orcid.core.utils.panoply.idleConnectionTimeout=3600 +org.orcid.core.utils.panoply.connectionTimeout=36000 +org.orcid.core.utils.panoply.jdbcUrl=xxx +org.orcid.core.utils.panoply.username=xxx From 36cb5b11e4d4eb4107e830b2664367cdb0c55d67 Mon Sep 17 00:00:00 2001 From: github actions Date: Fri, 11 Oct 2024 18:23:18 +0000 Subject: [PATCH 30/36] v2.66.3 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de70c422689..a8472b1d1b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.66.3 - 2024-10-11 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.2...v2.66.3) + ## v2.66.2 - 2024-10-10 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.1...v2.66.2) From 64fa3ca3a77695a61a8183b39cdf1583d1c9ac34 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru <62257307+Camelia-Orcid@users.noreply.github.com> Date: Fri, 11 Oct 2024 21:46:30 +0100 Subject: [PATCH 31/36] Revert 7093 revert 7091 9339 delete orgaffiliationrelation rows in panoply for affiliations deleted in the registry (#7106) * Revert "Revert "Added the code to store deleted items in panoply dw_deleted_items table"" * Fixed the failures in test suite * Fixed formatting added the default props for panoply redshift bean * removed the unused imports --------- Co-authored-by: Angel Montenegro Co-authored-by: Angel Montenegro --- .../impl/OrgAffiliationRelationDaoImpl.java | 56 +++++++++---------- .../resources/orcid-persistence-context.xml | 8 +-- .../utils/panoply/PanoplyDeletedItem.java | 24 ++++---- .../utils/panoply/PanoplyRedshiftClient.java | 13 ++--- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java index de1c3a5bf1f..bf849fbb405 100644 --- a/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java +++ b/orcid-persistence/src/main/java/org/orcid/persistence/dao/impl/OrgAffiliationRelationDaoImpl.java @@ -13,7 +13,6 @@ import org.orcid.utils.panoply.PanoplyRedshiftClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.commons.logging.Log; import org.orcid.persistence.aop.UpdateProfileLastModified; import org.orcid.persistence.aop.UpdateProfileLastModifiedAndIndexingStatus; import org.orcid.persistence.dao.OrgAffiliationRelationDao; @@ -23,12 +22,12 @@ import org.springframework.transaction.annotation.Transactional; public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl implements OrgAffiliationRelationDao { - + private static final Logger LOG = LoggerFactory.getLogger(OrgAffiliationRelationDaoImpl.class); - + @Value("${org.orcid.persistence.panoply.cleanup.production:false}") - private boolean enablePanoplyCleanupInProduction; - + private boolean enablePanoplyCleanupInProduction; + private static final String AFFILIATION_TYPE_DISTINCTION = "DISTINCTION"; private static final String AFFILIATION_TYPE_EDUCATION = "EDUCATION"; @@ -42,11 +41,11 @@ public class OrgAffiliationRelationDaoImpl extends GenericDaoImpl 0) { - if(enablePanoplyCleanupInProduction) { + if (query.executeUpdate() > 0) { + if (enablePanoplyCleanupInProduction) { PanoplyDeletedItem item = new PanoplyDeletedItem(); item.setItemId(orgAffiliationRelationId); item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); storeDeletedItemInPanoply(item); - } + } return true; } - return false; + return false; } - + private void storeDeletedItemInPanoply(PanoplyDeletedItem item) { - //Store the deleted item in panoply Db without blocking + // Store the deleted item in panoply Db without blocking CompletableFuture.supplyAsync(() -> { try { panoplyClient.addPanoplyDeletedItem(item); @@ -91,11 +90,11 @@ private void storeDeletedItemInPanoply(PanoplyDeletedItem item) { LOG.error("Cannot store deleted affiliation in panoply ", e); return false; } - }).thenAccept(result -> { - if(! result) { - LOG.error("Async call to panoply for : " + item.toString() + " Stored: "+ result); + }).thenAccept(result -> { + if (!result) { + LOG.error("Async call to panoply for : " + item.toString() + " Stored: " + result); } - + }); } @@ -241,13 +240,13 @@ public void removeOrgAffiliationByClientSourceId(String clientSourceId) { Query query = entityManager.createNativeQuery("DELETE FROM org_affiliation_relation WHERE client_source_id=:clientSourceId"); query.setParameter("clientSourceId", clientSourceId); query.executeUpdate(); - if(query.executeUpdate() > 0) { - if(enablePanoplyCleanupInProduction) { + if (query.executeUpdate() > 0) { + if (enablePanoplyCleanupInProduction) { PanoplyDeletedItem item = new PanoplyDeletedItem(); item.setClientSourceId(clientSourceId); item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); storeDeletedItemInPanoply(item); - } + } } } @@ -334,15 +333,15 @@ public void removeAllAffiliations(String orcid) { Query query = entityManager.createQuery("delete from OrgAffiliationRelationEntity where orcid = :orcid"); query.setParameter("orcid", orcid); query.executeUpdate(); - if(query.executeUpdate() > 0) { - if(enablePanoplyCleanupInProduction) { + if (query.executeUpdate() > 0) { + if (enablePanoplyCleanupInProduction) { PanoplyDeletedItem item = new PanoplyDeletedItem(); item.setOrcid(orcid); item.setDwTable(DW_PANOPLY_AFFILIATION_TABLE); storeDeletedItemInPanoply(item); - } + } } - + } @Override @@ -447,8 +446,7 @@ public void revertUserOBODetails(List ids) { @SuppressWarnings("unchecked") @Override public List getIdsForUserOBORecords(int max) { - Query query = entityManager - .createNativeQuery("SELECT id FROM org_affiliation_relation WHERE assertion_origin_source_id IS NOT NULL"); + Query query = entityManager.createNativeQuery("SELECT id FROM org_affiliation_relation WHERE assertion_origin_source_id IS NOT NULL"); query.setMaxResults(max); return query.getResultList(); } @@ -461,14 +459,14 @@ public List getIdsOfOrgAffiliationRelationsReferencingClientProfiles query.setMaxResults(max); return query.getResultList(); } - + @Override @UpdateProfileLastModifiedAndIndexingStatus @Transactional public void persist(OrgAffiliationRelationEntity affiliation) { super.persist(affiliation); } - + @Override @UpdateProfileLastModifiedAndIndexingStatus @Transactional diff --git a/orcid-persistence/src/main/resources/orcid-persistence-context.xml b/orcid-persistence/src/main/resources/orcid-persistence-context.xml index 554d47b39a6..629b3b163c1 100644 --- a/orcid-persistence/src/main/resources/orcid-persistence-context.xml +++ b/orcid-persistence/src/main/resources/orcid-persistence-context.xml @@ -460,13 +460,13 @@ - + - - - + + + diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java index 378b0185227..a39df453cde 100644 --- a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java +++ b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyDeletedItem.java @@ -6,50 +6,54 @@ public class PanoplyDeletedItem { private Long itemId; private String clientSourceId; private String orcid; - + public final String DW_ORG_AFFILIATION_RELATION = "dw_org_affiliation_relation"; public final String DW_WORK = "dw_work"; - + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + public String getDwTable() { return dwTable; } + public void setDwTable(String dwTable) { this.dwTable = dwTable; } + public Long getItemId() { return itemId; } + public void setItemId(Long itemId) { this.itemId = itemId; } + public String getClientSourceId() { return clientSourceId; } + public void setClientSourceId(String clientSourceId) { this.clientSourceId = clientSourceId; } + public String getOrcid() { return orcid; } + public void setOrcid(String orcid) { this.orcid = orcid; } - + @Override public String toString() { - return "PanoplyDeletedItem{" + - "id=" + id + - ", dwTable='" + dwTable + '\'' + - ", itemId='" + itemId + '\'' + - ", clientSourceId='" + clientSourceId + '\'' + - ", orcid='" + orcid + '\'' + - '}'; + return "PanoplyDeletedItem{" + "id=" + id + ", dwTable='" + dwTable + '\'' + ", itemId='" + itemId + '\'' + ", clientSourceId='" + clientSourceId + '\'' + + ", orcid='" + orcid + '\'' + '}'; } } diff --git a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java index 3499593eb27..77c5db8ef16 100644 --- a/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java +++ b/orcid-utils/src/main/java/org/orcid/utils/panoply/PanoplyRedshiftClient.java @@ -8,7 +8,6 @@ import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; - import java.util.Date; import javax.annotation.Resource; @@ -21,16 +20,16 @@ public class PanoplyRedshiftClient { private static final Logger LOG = LoggerFactory.getLogger(PanoplyRedshiftClient.class); - + @Autowired @Qualifier("panoplyJdbcTemplate") private JdbcTemplate panoplyJdbcTemplate; - - + public int addPanoplyDeletedItem(PanoplyDeletedItem item) { - LOG.debug("Adding deleted item to panoply DB: " + item.toString()); + LOG.debug("Adding deleted item to panoply DB: " + item.toString()); String sql = "INSERT INTO dw_deleted_items (item_id, orcid, client_source_id, date_deleted, dw_table) VALUES (?, ?, ?, ?, ?)"; - return panoplyJdbcTemplate.update(sql, item.getItemId(), item.getOrcid(), item.getClientSourceId(), new java.sql.Timestamp(new Date().getTime()), item.getDwTable()); + return panoplyJdbcTemplate.update(sql, item.getItemId(), item.getOrcid(), item.getClientSourceId(), new java.sql.Timestamp(new Date().getTime()), + item.getDwTable()); } - + } From 14d1885acdb8d6cfa45fb81b4fea5d32b121e05b Mon Sep 17 00:00:00 2001 From: github actions Date: Fri, 11 Oct 2024 21:15:13 +0000 Subject: [PATCH 32/36] v2.66.4 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8472b1d1b9..b9dc9b81240 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.66.4 - 2024-10-11 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.3...v2.66.4) + ## v2.66.3 - 2024-10-11 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.2...v2.66.3) From 9aaeae2805f077f3ebcadb1a8e38c4911a90681d Mon Sep 17 00:00:00 2001 From: andrej romanov <50377758+auumgn@users.noreply.github.com> Date: Wed, 16 Oct 2024 00:00:01 +0300 Subject: [PATCH 33/36] Add verification date to email endpoint (#7104) * Added the date verified when verifying an email address * fix domain modification date value * formatting * test verification date logic * update orcid model version * set up verification date in the endpoint * fix verification date endpoint logic * configure mapper to process verification dates * add verification assertions --------- Co-authored-by: Camelia Dumitru Co-authored-by: Angel Montenegro --- .../adapter/v3/impl/MapperFacadeFactory.java | 1 + .../java/org/orcid/pojo/ajaxForm/Email.java | 18 ++++++++++++++++++ .../java/org/orcid/pojo/ajaxForm/Emails.java | 2 +- .../pojo/ajaxForm/ProfileEmailDomain.java | 5 +++-- .../adapter/v3/JpaJaxbEmailAdapterTest.java | 4 ++++ pom.xml | 2 +- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/orcid-core/src/main/java/org/orcid/core/adapter/v3/impl/MapperFacadeFactory.java b/orcid-core/src/main/java/org/orcid/core/adapter/v3/impl/MapperFacadeFactory.java index f0c2c2f28b9..0e0cb01658b 100644 --- a/orcid-core/src/main/java/org/orcid/core/adapter/v3/impl/MapperFacadeFactory.java +++ b/orcid-core/src/main/java/org/orcid/core/adapter/v3/impl/MapperFacadeFactory.java @@ -500,6 +500,7 @@ public MapperFacade getEmailMapperFacade() { emailClassMap.field("primary", "primary"); emailClassMap.field("verified", "verified"); emailClassMap.fieldMap("visibility", "visibility").converter("visibilityConverter").add(); + emailClassMap.field("verificationDate.value", "dateVerified"); addV3DateFields(emailClassMap); registerSourceConverters(mapperFactory, emailClassMap); emailClassMap.register(); diff --git a/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Email.java b/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Email.java index 7b65d9f3190..930174b27bf 100644 --- a/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Email.java +++ b/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Email.java @@ -32,6 +32,8 @@ public class Email implements ErrorsInterface { private Date lastModified; + private Date verificationDate; + private List errors = new ArrayList(); public static Email valueOf(org.orcid.jaxb.model.v3.release.record.Email e) { @@ -76,6 +78,14 @@ public static Email valueOf(org.orcid.jaxb.model.v3.release.record.Email e) { lastModifiedDate.setDay(String.valueOf(e.getLastModifiedDate().getValue().getDay())); email.setLastModified(lastModifiedDate); } + + if (e.getVerificationDate() != null) { + Date verificationDate = new Date(); + verificationDate.setYear(String.valueOf(e.getVerificationDate().getValue().getYear())); + verificationDate.setMonth(String.valueOf(e.getVerificationDate().getValue().getMonth())); + verificationDate.setDay(String.valueOf(e.getVerificationDate().getValue().getDay())); + email.setVerificationDate(verificationDate); + } } return email; } @@ -187,6 +197,14 @@ public void setLastModified(Date lastModified) { this.lastModified = lastModified; } + public Date getVerificationDate() { + return verificationDate; + } + + public void setVerificationDate(Date verificationDate) { + this.verificationDate = verificationDate; + } + public List getErrors() { return errors; } diff --git a/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Emails.java b/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Emails.java index 1ea3ad73889..3d808766fc9 100644 --- a/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Emails.java +++ b/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Emails.java @@ -33,7 +33,7 @@ public static Emails valueOf(org.orcid.jaxb.model.v3.release.record.Emails e, Li public org.orcid.jaxb.model.v3.release.record.Emails toV3Emails() { org.orcid.jaxb.model.v3.release.record.Emails v3Emails = new org.orcid.jaxb.model.v3.release.record.Emails(); - if(emails != null && !emails.isEmpty()) { + if (emails != null && !emails.isEmpty()) { for(Email email : emails) { v3Emails.getEmails().add(email.toV3Email()); } diff --git a/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/ProfileEmailDomain.java b/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/ProfileEmailDomain.java index 3ac0d064246..422442a130e 100644 --- a/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/ProfileEmailDomain.java +++ b/orcid-core/src/main/java/org/orcid/pojo/ajaxForm/ProfileEmailDomain.java @@ -26,7 +26,7 @@ public static ProfileEmailDomain valueOf(ProfileEmailDomainEntity ed) { Date createdDate = new Date(); LocalDate date = ed.getDateCreated().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); createdDate.setYear(String.valueOf(date.getYear())); - createdDate.setMonth(String.valueOf(date.getMonth())); + createdDate.setMonth(String.valueOf(date.getMonthValue())); createdDate.setDay(String.valueOf(date.getDayOfMonth())); createdDate.setTimestamp(ed.getDateCreated().toInstant().toEpochMilli()); emailDomain.setCreatedDate(createdDate); @@ -36,10 +36,11 @@ public static ProfileEmailDomain valueOf(ProfileEmailDomainEntity ed) { Date lastModifiedDate = new Date(); LocalDate date = ed.getLastModified().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); lastModifiedDate.setYear(String.valueOf(date.getYear())); - lastModifiedDate.setMonth(String.valueOf(date.getMonth())); + lastModifiedDate.setMonth(String.valueOf(date.getMonthValue())); lastModifiedDate.setDay(String.valueOf(date.getDayOfMonth())); emailDomain.setLastModified(lastModifiedDate); } + } return emailDomain; } diff --git a/orcid-core/src/test/java/org/orcid/core/adapter/v3/JpaJaxbEmailAdapterTest.java b/orcid-core/src/test/java/org/orcid/core/adapter/v3/JpaJaxbEmailAdapterTest.java index 6fb86a0a529..65a70e2e6ac 100644 --- a/orcid-core/src/test/java/org/orcid/core/adapter/v3/JpaJaxbEmailAdapterTest.java +++ b/orcid-core/src/test/java/org/orcid/core/adapter/v3/JpaJaxbEmailAdapterTest.java @@ -101,6 +101,7 @@ public void testEmailToEmailEntity() throws JAXBException { assertNotNull(entity); assertNull(entity.getDateCreated()); assertNull(entity.getLastModified()); + assertNull(entity.getDateVerified()); assertEquals("user1@email.com", entity.getEmail()); assertEquals(org.orcid.jaxb.model.common_v2.Visibility.PUBLIC.name(), entity.getVisibility()); @@ -119,6 +120,8 @@ public void testEmailEntityToEmail() throws IllegalAccessException { assertEquals(DateUtils.convertToDate("2015-06-05T10:15:20"), DateUtils.convertToDate(email.getCreatedDate().getValue())); assertNotNull(email.getLastModifiedDate()); assertEquals(DateUtils.convertToDate("2015-06-05T10:15:20"), DateUtils.convertToDate(email.getLastModifiedDate().getValue())); + assertNotNull(email.getVerificationDate()); + assertEquals(DateUtils.convertToDate("2015-06-05T10:15:20"), DateUtils.convertToDate(email.getVerificationDate().getValue())); assertEquals("email@test.orcid.org", email.getEmail()); assertEquals(Visibility.PRIVATE, email.getVisibility()); @@ -159,6 +162,7 @@ private EmailEntity getEmailEntity() throws IllegalAccessException { Date date = DateUtils.convertToDate("2015-06-05T10:15:20"); EmailEntity result = new EmailEntity(); DateFieldsOnBaseEntityUtils.setDateFields(result, date); + result.setDateVerified(date); result.setEmail("email@test.orcid.org"); result.setCurrent(true); result.setPrimary(true); diff --git a/pom.xml b/pom.xml index 102707e2b93..c6024f0e181 100644 --- a/pom.xml +++ b/pom.xml @@ -918,7 +918,7 @@ the software. org.orcid orcid-model - 3.3.1 + 3.3.2 org.orcid From aa2c36a03a6ca8013c0b7b956e1ce106ff722d64 Mon Sep 17 00:00:00 2001 From: github actions Date: Tue, 15 Oct 2024 21:19:12 +0000 Subject: [PATCH 34/36] v2.66.5 changelog update --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9dc9b81240..a641ac3d527 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v2.66.5 - 2024-10-15 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.4...v2.66.5) + ## v2.66.4 - 2024-10-11 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.3...v2.66.4) From cba99cf85602430a30fdc6ec465397f4fef8ceba Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Sat, 26 Oct 2024 02:31:38 -0700 Subject: [PATCH 35/36] update license reference Signed-off-by: Emmanuel Ferdman --- PROJECTS.md | 2 +- TESTAUTO.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PROJECTS.md b/PROJECTS.md index edeb832269a..9f4421d869c 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -12,7 +12,7 @@ Also see our active contributors: [CREDITS.md](https://github.com/ORCID/ORCID-Wo > > Copyright (c) 2013 ORCID, Inc. > Licensed under an MIT-Style License (MIT) -> https://github.com/ORCID/ORCID-Source/blob/master/LICENSE.md +> https://github.com/ORCID/ORCID-Source/blob/main/LICENSE > http://orcid.org/OpenSource/license > > This copyright and license information (including a link to the full license) shall be included in its entirety in all copies or substantial portion of the software. diff --git a/TESTAUTO.md b/TESTAUTO.md index 9233ff29480..bc9f89b445e 100644 --- a/TESTAUTO.md +++ b/TESTAUTO.md @@ -124,5 +124,5 @@ Mac: ```/Applications/Firefox.app/Contents/MacOS/firefox-bin``` [src/test/resources/test-client.properties](https://github.com/ORCID/ORCID-Source/blob/master/orcid-integration-test/src/test/resources/test-client.properties) # License -See [LICENSE.md](https://github.com/ORCID/ORCID-Source/blob/master/LICENSE.md) +See [LICENSE](https://github.com/ORCID/ORCID-Source/blob/main/LICENSE) From a895ef73168df04de35b0fbf80cefccd6951b671 Mon Sep 17 00:00:00 2001 From: github actions Date: Mon, 28 Oct 2024 13:24:34 +0000 Subject: [PATCH 36/36] v2.66.6 changelog update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a641ac3d527..6665393febc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## v2.66.6 - 2024-10-28 + +[Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.5...v2.66.6) + +- [#7111](https://github.com/ORCID/ORCID-Source/pull/7111): update license reference + ## v2.66.5 - 2024-10-15 [Full Changelog](https://github.com/ORCID/ORCID-Source/compare/v2.66.4...v2.66.5)