From c5bcb8e26aa662c11088af940f9271e7828b8934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20S=C3=A4rkikoski?= Date: Wed, 29 Mar 2023 10:17:12 +0300 Subject: [PATCH] 1.22 release (#147) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Cscttv 2132 (#24) * Add openshift config for api devel. * Modify Docker build path. * Add openshift config for identityserver devel. * Test permission change in container app folder. * Modify run time permissions * Change SDK version in Identityserver build. * Change build branch to devel. Change Rahti container image path. * Remove researchfi prefix from Openshift config. * Add README for api application. * Upgrade Nuget packages. * CSCTTV-2132_2 (#25) * Modify Openshift template and Dockerfile for Identityserver. * Modify image pull path. * Modify image pull path. * Add README in Identityserver project. * Update README.md * Update README.md * Modify Git source branch and container path in Identityserver template. * Remove Identityserver tempkey.jwk and add it in gitignore. * Change app folder permission in Identityserver container. * Do not initialize ElasticsearchService without required configuration values. * CSCTTV-2123 Elasticsearch sync (#26) * First draft of how data can be synced in Elasticsearch. * Elasticsearch connection parameters from configuration. * Add data types for Elasticsearch. * Add more data in Elasticsearch person index. * Delete tempkey.jwk * Add Elasticsearch environment variables in api README. Add identityserver's tempkey.jwk in .gitignore. * Simplify Elasticsearch service and change it to singleton instead of scoped service. * Use connection resiliency with SQL Server provider. * Always set field Modified to current timestamp when creating a new entry in database. * Add more logging in ElasticsearchService. * Improve handling of NEST error messages when adding or deleting entry in Elasticsearch. * Remove unused controller. * Use raw SQL query for getting DimUserProfile based on ORCID Id in DimPid. Clean up startup.cs dependencies. * Use raw SQL query when retrieving ORCID registered data source from DimRegisteredDataSource. * Upgrade Nuget packages in api project. * Code clean up, remove repetitive code. * Use raw sql when updating FactFieldValue table. Change created and modified timestamp to DateTime.UtcNow instead of DateTime.Now. Add namespace api.models.ProfileEditor. * Add unit tests for TtvSqlService. In TtvSqlService add own function for getting FactFieldValues FK column name based on field identifier. * Simplify queries which get data for profile editor and elasticsearch index. * When getting data for profile editor, get only those DimFieldDisplaySettings, which have at least one related FactFieldValue. * Update Elasticsearch in a background task. (#27) * When profile is created, include ORCID name automatically in profile. * In ORCID controller remove unnecessary retrieval of DimKnownPerson entity. * Remove multiple publicationIds from profile in the same api query. * Remove cached profiledata when publications are added or removed. * Use field identifier 550 with ORCID publications. When userprofile is deleted, remove cached profiledata and remove Elasticsearch entry in background task. * Enable split SQL query behaviour globally. Fix bug in ORCID publication handling. * Call SaveChangesAsync only once when ORCID data is imported. * Call SaveChangesAsync only once when adding demo data into user profile. * Modify Identityserver Javascript client configuration handling. * Add cooperation selection api (demo) (#28) * Add draft version of cooperation selection api. * Modify cooperation choice text content. * Add Swagger documentation. (#29) * Add Swagger documentation. * Simplify cooperationdemo api. Swagger documentation improvements. * Comment out Swagger, because the configuration does not work in Docker build. * Enable Swagger in development environment * Modify xml documentation generation. Modify environment handling in startup. * Add LanguageService. (#30) * Language service and name translation improvements. * Add DimUserChoice in Ttv model. Add DimUserChoice handling in CooperationChoicesController. (#31) * Compress api responses. * Profile API for adding and removing funding decisions. (#32) * Add controller and models for DimFundingDecision handling. * Add funding decision handling in user profile. * Add funding decision in demo data. * Add DimFundingDecision demo data. * Modify demo data. Modify FundingDecisionController functionality. * Simplify addFungingDecision API response. * CSCTTV-1703 research dataset handling in profile API (#33) * Add controller and models for DimResearchDataset handling. * Add relation between DimResearchDataset and FactFieldValues. Modify FundingDecisionController to use updated Ttv data model. * Add part of research dataset demo data. * Modify research dataset demo data handling. Modify demo data deletion. * Modify research dataset structure in profile data API response. * Comment out profile data query items. * Include ORCID ID in demodata source id field. * Modify research dataset demo data. * Fix bug in research dataset demodata creation. Modify user profile deletion. * Add funding decision and research dataset column names in TtvSqlService. * Optimize user profile and related data deletion. * Add department name in affiliation. Demo implementation, not production ready. (#34) * Improve handling of null values in name translation. * Restore previous functionality in user profile deletion. * Change funding decision handling to use projectId instead of funderProjectNumber. (#35) * Fix typo in funding decision property name. * Add OpenShift templates for demo version. * Change start and end date property names in funding decision item. * Add property datasetCreated in research dataset item. * Change demo version openshift build config git branch. * Comment out querying DimIdentifierlessData because of data model mismatch. * Add user profile id in cooperation item query. * Return API response immediately when there are no items to add or remove. * Add debug controller for getting debug data and statistics. * Sql model update 2021 12 (#37) * Remove log print of user profile existence check. * Add api response compression. * Ttv model update according to latest SQL database structure. Major change to handling of registered data source, work in progress. * Version which builds without errors. Elasticsearch synchronization and debug controller have some parts of code commented out. * Modify user profile creation, adding demo data and adding ORCID data. * Modify registered data source handling in profile data load. * Fix bug, which prevents deleting DimFieldDisplaySettings related to user profile. * Move profile editor data retrieval code into UserProfileService. * Modify profile data handling in Elasticsearch synchronization. * Modify SourceId field handling. Fix ORCID import bugs in DimName and DimResearcherDescription. * Handle missing name element when parsing ORCID record. * Upgrade Nuget packages. Modify DemoDataService. * Filter query to get only ORCID related entities. Remove manual adjustment of EntityState. * Get list of available FieldIdentifiers from UserProfileService. Add unit test to validate FieldIdentifier list content. * Add type code in publication and ORCID publication. (#38) * Fix bug where fromCache property was not set in ApiResponseProfileDataGet. * Take DOI from DimPublication.Doi instead of DimPublication.DoiHandle * Set ORCID member api scopes. Store and update user's ORCID access token on ORCID login. (#39) * Store ORCID tokens from Keycloak external IDP token endpoint. Add TokenService. (#40) * Add missing dependency injection in TokenService * Add Keycloak account linking. Add named http clients. Modify configuration parameters. (#41) * Require specific scope and orcid claim in controller authorization policy. (#42) * Add DuplicateHandlerService (#43) * Add DupplicateHandlerService and unit tests. Add temporary models and controller for testing purposes. * Modify DuplicateHandlerService unit tests * Logout and delete Keycloak user when user profile is deleted. (#44) * EF model update. Registered data source handling changes. (#45) * EF model scaffolded from test database on 5.5.2022. * Modify ORCID and Tiedejatutkimus.fi data source handling. * Add missing model files. * Store ORCID and TTV registered data source and organization values into a singleton service on startup. (#46) * Fixes suggested by Visual Studio code analyzer (#47) * Remove IdentityServer (#48) * Affiliation organization and department name handling in ORCID import (#49) * Add OrcidImportService. Move logic from controller to service. Modify Orcid json parser unit tests. * Add OrganizationHandlerService. Modify organization name handling in ORCID import and profile data deletion. * Modify affiliation related organization search in ORCID import. Modify affiliation deletion. * Modify affiliation department name handling. * Modify ORCID disambiguation source mapping, add unit test. * Move logic from controllers to services. (#50) * Improvements in background Elasticsearch index update (#51) * Queue background tasks according to Microsoft documentation. * Check if Elasticsearch sync feature is enabled before adding items to task queue. * Update NuGet packages (#52) * Add ” (test)” in temporary organization names * Update TTV model. Add DueDateDueTime into DimCallProgramme * Update TTV model change. PK in BrGrantedPermission * Remove demo data related code from user profile deletion. * Do not delete DimResearchDataset on profile deletion * Migrate from ASP.NET Core 5.0 to 6.0 (#53) * Add sharing API for profile editor (#54) * Add SharingController and SharingService * Profile sharing related database queries on application startup. * DimReferenceData handling when setting user profile default permissions. * Add SharingController and draft data * Add API endpoints for getting available sharing permissions and purposes. Language service bugfix. * Rename sharing purpose related model. * Add endpoints for listing, adding and removing of share permissions. * Change OKM organization id (#55) * Add Openshift template for Artifactory build. Remove unused templates. (#56) * Startup.cs code clean up. * Use interfaces in dependecy injection. (#57) * Add Serilog for logging. (#58) * Add GitHub codeql (#61) * Add GitHub action CodeQL. * Modify CodeQL GitHub action * Check only csharp in GitHub action CodeQL. * Modify log format. * Modify log message content. (#62) * CSCTTV-2724 Improvements in profile creation (#63) * Improved TTV database search when creating user profile. * Add research activity search on profile creation. * CSCTTV-2720 Improve testability (#64) * Add debug methods to create and delete a user profile to any ORCID ID in dim_pid. * Get ORCID record from public API when a specific flag is set in access token. * Fix bug in parsing of ORCID record education element * Import from ORCID only one entry of the same publication. (#65) * Enable database command logging * Use TagWith in queries to make debug log more readable. * Optimized profile data query using Dapper (#66) * Add Dapper. Get profiledata using raw sql. * Profile data person section query converted to raw sql. * Partially completed version of new profile data query using Dapper. * Add dim_education handling in new profile data query. * Add dim_publication and dim_orcid_publication handling in new profile data query. * Moved profile data SQL string into TtvSqlService. Use new profile data query in Elasticsearch index update. * Add missing ITtvSqlService.cs, which was dropped by malfunctioning IDE. * Removed old code from UserProfileService * Profile data deletion using Dapper (#67) * Initial code for deleting user profile using Dapper. Modify unit tests. Upgrade packages. * First working version of profile data deletion using Dapper. * Fix bug in deleting ORCID put codes from dim_pid. Add unit tests SQL statement creation. * Removed commented code. * Profile data response using new data structure. (#68) * New data structure in profile data response * Profile data personal section converted to new data structure. * Profile data activity section converted to new data structure. * Remove commented code and temporary modification in controller. * Modify DuplicateHandlerService unit tests. * Fix bug in Swagger documentation. Set controller route names explicitly. * Optimized profile deletion (#69) * Delete multiple IDs from dim_pid and dim_orcid_publication in the same SQL statement. * Delete multiple rows in one SQL statement using WHERE id IN condition * Update TTvSqlService unit tests. * Update field identifiers, unit tests and dependencies. * Use Automapper to create Elasticsearch data object from profile editor data object. (#70) * Limit profiledata in Elastic index to published items only. (#71) * Add property activitiesAndRewards into profiledata. Add property researchDatasets into Elasticsearch profiledata. (#72) * Update SQL query for dim_research_activity. Update profiledata contents. (#73) * Funding decision handling in SQL query and API response (#74) * Research dataset handling in SQL query and API response (#75) * Fix missing itemMeta in profile editor data. * Add API endpoint accountdelete for removing Keycloak user. (#76) * Cscttv 2799 hide national identification number (#77) * Add own folder structure for Keycloak related files. * Modify Java project naming. Add readme. * Modify Keycloak Dockerfile * Add custom Keycloak extension into build_dependencies folder. * Add OpenShift template for Keycloak devel. Modify Keycloak Dockerfile. (#78) * Rename Keycloak OpenShift template entries * Add Keycloak version number 19 in OpenShift template to avoid collision with old installation. * Fix bug in Keycloak custom provider URL. * Comment out automatic certificate generation in Keycloak container. * Add list of unique data sources in profile data and Elasticsearch index. (#79) * Add SectorId in organization data. (#80) * Add property primaryValue in Elasticsearch data. (#81) * Remove obsolete API code. Organize models. Update dependencies. (#82) * Remove DemoDataService * Reduce EntityFramework database log level. * Remove duplicate field PrimaryValue from elasticsearch model. (#83) * Remove duplicate PrimaryValue fields from Elasticsearch models. (#84) * Rename controller and route for profiledata. (#85) * Add OpenShift templates for QA and production. (#86) * Fix bug where duplicate dates are inserted during ORCID import. (#88) * Fix bug in cache key naming. (#89) * Set production CORS allowed origins. (#90) * Change ORCID and TTV data source organization names. Add UtilityService unit tests. (#91) * Comment out sharing feature related database query. (#92) * Add QA domains in allowed origins for production. (#93) * Add affiliation organization sector data. (#94) * Check that Elasticsearch index exists. Add index mapping. (#95) * Check that Elasticsearch index exists. Add Elasticsearch mapping for sector in afiiliation. * Fix bug in ElasticsearchService constructor. * Modify DimKnownPerson handling in profile creation phase. (#96) * Add role code and name in research activity. (#97) * Allow all data sources when adding TTV data based on known person dim_names (#98) * Revert allowing all data sources (#99) * Add profile settings controller and possibility to hide profile from portal. (#100) * Improved TTV data collection (#101) * New version of TTV data collection * Fix incorrect DimFieldDisplaySettings reference in TTV data collection. * Add research activity type handling in profile editor data. (#102) * Name and other name handling when collecting TTV data. (#103) * Modify Elasticsearch person index mapping (#104) * Change how funding decisions are searched during profile creation. (#105) * Web link handling in TTV data collection (#106) * Fix bug where PATCH fails on research activity. (#107) * Filter dim_names based on dim_registered_data_source.name (#108) * Trigger Elasticsearch person index update from controllers (#110) * Handle multi level organization relationship in affiliation organization name (#112) * Prevent duplicates and -1 rows in fact_contribution SQL query. (#113) * Add fields in profile editor and elasticsearch publication. (#114) * Add field authorsText to publication * Add fields JournalName, ConferenceName and ParentPublication name into publication. * ORCID import improved checking and simplified query. (#115) * Ignore possible duplicates when adding items to profile. (#116) * Make sure publication year is null instead of 0. (#117) * Entity framework model update. Scaffolded from database. (#118) * Add ORCID webhook handling (#119) * Add WebhookController. Add backgroung task for updating ORCID data. * ORCID webhook registration * Improve OrcidApiService unit tests. * Add ORCID webhook registration and unregistration API calls. * Modify configuration parameter names for ORCID webhook. Improve OrcidApiService unit tests. * Upgrade NuGet packages. (#120) * Add AdminController. Add admin commands for ORCID webhooks. Add comments. (#121) * Add admin command to update user profile in Elasticsearch (#122) * TTV model update 28.12.2022 (#123) * Add GitHub action: build and unit test (#124) * Ttv model update 30.12.2022 (#125) * Ttv model update 3.1.2023 (#126) * Cscttv 2075 opensearch logging configuration (#127) * Add custom NuGet source for local packages. Add custom OpenSearch sink for Serilog. * Structured log messages. * Change log messages to use structured format. * Structured log messages in services. * Add log message in AccountLinkController * Handle NuGet custom files in Docker build * Modify Dockerfile * Modify Dockerfile * Modify Dockerfile * Modify Dockerfile * Change log model folder name to avoid gitignore * Modify Serilog config in appsettings.json * TTV model update 10.1.2023 (#128) * TTV model update 10.1.2023 * Add missing models * Store log user information in a variable in admin controller. (#129) * Define outputTemplate for Serilog console sink. (#130) * Use monthly indexes in OpenSearch logging (#131) * CSCTTV-3117 deleted orcid data handling (#133) * Handle deletion of ORCID name, web link, researcher description and email address. * Handle deletion of ORCID keywords, external ids, educations and publications * Handle affiliation and related identifierless data deletion * Update Elasticsearch after ORCID webhook (#134) * TTV model update 16.2.2023 (#135) * Remove obsolete models (#136) * Improve ORCID webhook logging (#137) * Fix controller annotation which was breaking Swagger UI (#138) * Add LocalIdentifier in DimAffiliation. (#141) * Profile only publication and research activity (#142) * TTV model update according to CSCTTV-2855 and CSCTTV-2858 * Add missing foreing key in helper method. TTV model update 16.3.2023. * Use IsNullOrWhiteSpace to check if affiliation department name is valid in ORCID import. This prevents inserting null value into dim_identifierless_data. (#143) * Add more unit tests for UserProfileService. (#144) * Cscttv 3206 send logs to logstash using serilog http sink (#145) * Use Serilog HttpSink * Remove Serilog.Sinks.OpenSearch. Add Serilog.Sinks.Http. * Modify Serilog configuration * Modify Serilog configuration * Modify Serilog configuration. * Modify Serilog configuration. * Use custom Http client with Serilog Http sink to enable basic authentication. Add Serilog debug logging. * Fix bug from merge * Fix bug from merge in TtvContext * Fix bug from merge in DimCallProgramme --- .../DuplicateHandlerServiceTest.cs | 88 +- .../Services_Tests/TtvSqlServiceTest.cs | 35 +- .../Services_Tests/UserProfileServiceTest.cs | 187 ++- .../src/api/Controllers/AdminController.cs | 6 +- .../src/api/Controllers/OrcidController.cs | 27 +- .../src/api/Controllers/WebhookController.cs | 133 +- aspnetcore/src/api/Models/Common/Constants.cs | 2 +- .../src/api/Models/Orcid/OrcidImportHelper.cs | 29 + .../ProfileEditor/ProfileDataFromSql.cs | 12 +- .../BasicAuthenticatedHttpClient.cs | 50 + .../api/Models/StructuredLog/LogContent.cs | 7 + .../Ttv/BrCallProgrammeDimCallProgramme.cs | 16 - .../Ttv/BrDimReferencedataDimCallProgramme.cs | 16 - .../Models/Ttv/BrEsfriDimInfrastructure.cs | 16 - ...dDisplaySettingsDimRegisteredDataSource.cs | 16 - .../Models/Ttv/BrFieldOfArtDimPublication.cs | 16 - .../Ttv/BrFieldOfEducationDimPublication.cs | 16 - .../Ttv/BrFieldOfScienceDimFundingDecision.cs | 16 - .../Ttv/BrFieldOfScienceDimPublication.cs | 16 - .../Ttv/BrFundingDecisionDimFieldOfArt.cs | 16 - .../Ttv/BrInfrastructureDimFieldOfScience.cs | 16 - .../Models/Ttv/BrKeywordDimFundingDecision.cs | 16 - .../api/Models/Ttv/BrKeywordDimPublication.cs | 16 - .../Models/Ttv/BrLanguageCodesForDataset.cs | 13 - .../Models/Ttv/BrMerilDimInfrastructure.cs | 16 - .../Ttv/BrOrganizationsFundCallProgramme.cs | 16 - .../Models/Ttv/BrPredecessorOrganization.cs | 16 - .../Models/Ttv/BrPreviousFundingDecision.cs | 16 - .../Models/Ttv/BrRelatedFundingDecision.cs | 16 - .../Models/Ttv/BrResearchDatasetDimKeyword.cs | 13 - .../Ttv/BrResearcherToResearchCommunity.cs | 29 - .../src/api/Models/Ttv/DimAffiliation.cs | 1 + .../src/api/Models/Ttv/DimCallProgramme.cs | 5 +- aspnetcore/src/api/Models/Ttv/DimDate.cs | 4 + aspnetcore/src/api/Models/Ttv/DimEvent.cs | 2 + .../src/api/Models/Ttv/DimFieldOfScience.cs | 18 - .../DimFieldOfScienceDimResearchActivity.cs | 16 - aspnetcore/src/api/Models/Ttv/DimGeo.cs | 2 + .../src/api/Models/Ttv/DimKnownPerson.cs | 4 +- .../Ttv/DimKnownPersonDimFieldOfScience.cs | 16 - .../src/api/Models/Ttv/DimOrganization.cs | 2 + aspnetcore/src/api/Models/Ttv/DimPid.cs | 4 +- ...cation.cs => DimProfileOnlyPublication.cs} | 43 +- .../Ttv/DimProfileOnlyResearchActivity.cs | 43 + .../src/api/Models/Ttv/DimReferencedatum.cs | 28 +- .../api/Models/Ttv/DimRegisteredDataSource.cs | 6 +- .../src/api/Models/Ttv/FactFieldValue.cs | 8 +- aspnetcore/src/api/Models/Ttv/TtvContext.cs | 1181 ++++++++--------- aspnetcore/src/api/Program.cs | 30 +- .../api/Services/DuplicateHandlerService.cs | 24 +- aspnetcore/src/api/Services/ITtvSqlService.cs | 2 +- .../src/api/Services/IUserProfileService.cs | 2 +- .../src/api/Services/OrcidImportService.cs | 511 +++++-- aspnetcore/src/api/Services/TtvSqlService.cs | 29 +- .../src/api/Services/UserProfileService.cs | 47 +- aspnetcore/src/api/api.csproj | 4 +- aspnetcore/src/api/appsettings.json | 12 +- 57 files changed, 1579 insertions(+), 1368 deletions(-) create mode 100644 aspnetcore/src/api/Models/Orcid/OrcidImportHelper.cs create mode 100644 aspnetcore/src/api/Models/SerilogHttpSink/BasicAuthenticatedHttpClient.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrCallProgrammeDimCallProgramme.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrDimReferencedataDimCallProgramme.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrEsfriDimInfrastructure.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrFieldDisplaySettingsDimRegisteredDataSource.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrFieldOfArtDimPublication.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrFieldOfEducationDimPublication.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimFundingDecision.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimPublication.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrFundingDecisionDimFieldOfArt.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrInfrastructureDimFieldOfScience.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrKeywordDimFundingDecision.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrKeywordDimPublication.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrLanguageCodesForDataset.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrMerilDimInfrastructure.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrOrganizationsFundCallProgramme.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrPredecessorOrganization.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrPreviousFundingDecision.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrRelatedFundingDecision.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrResearchDatasetDimKeyword.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/BrResearcherToResearchCommunity.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/DimFieldOfScience.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/DimFieldOfScienceDimResearchActivity.cs delete mode 100644 aspnetcore/src/api/Models/Ttv/DimKnownPersonDimFieldOfScience.cs rename aspnetcore/src/api/Models/Ttv/{DimOrcidPublication.cs => DimProfileOnlyPublication.cs} (58%) create mode 100644 aspnetcore/src/api/Models/Ttv/DimProfileOnlyResearchActivity.cs diff --git a/aspnetcore/src/api.Tests/Services_Tests/DuplicateHandlerServiceTest.cs b/aspnetcore/src/api.Tests/Services_Tests/DuplicateHandlerServiceTest.cs index b9d4fbb7..784233c1 100644 --- a/aspnetcore/src/api.Tests/Services_Tests/DuplicateHandlerServiceTest.cs +++ b/aspnetcore/src/api.Tests/Services_Tests/DuplicateHandlerServiceTest.cs @@ -1,5 +1,5 @@ -using Xunit; -using System.Collections.Generic; +using Xunit; +using System.Collections.Generic; using api.Services; using api.Models; using api.Models.Common; @@ -7,144 +7,144 @@ using api.Models.ProfileEditor.Items; using api.Models.Ttv; -namespace api.Tests -{ - [Collection("Duplicate handler service tests.")] +namespace api.Tests +{ + [Collection("Duplicate handler service tests.")] public class DuplicateHandlerServiceTests_HasSameDoiButIsDifferentPublication { [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication type code is not A3, A4, B2, B3, D2, D3 or E1")] public void hasSameDoiButIsDifferentPublication_010() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "code123" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code A3, names differ.")] public void hasSameDoiButIsDifferentPublication_020() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "A3" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code A3, both have the same name.")] public void hasSameDoiButIsDifferentPublication_030() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "A3" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code A4, names differ.")] public void hasSameDoiButIsDifferentPublication_040() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "A4" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code A4, both have the same name.")] public void hasSameDoiButIsDifferentPublication_050() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "A4" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code B2, names differ.")] public void hasSameDoiButIsDifferentPublication_060() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "B2" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code B2, both have the same name.")] public void hasSameDoiButIsDifferentPublication_070() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "B2" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code B3, names differ.")] public void hasSameDoiButIsDifferentPublication_080() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "B3" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code B3, both have the same name.")] public void hasSameDoiButIsDifferentPublication_090() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "B3" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code D2, names differ.")] public void hasSameDoiButIsDifferentPublication_100() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "D2" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code D2, both have the same name.")] public void hasSameDoiButIsDifferentPublication_110() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "D2" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code D3, names differ.")] public void hasSameDoiButIsDifferentPublication_120() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "D3" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code D3, both have the same name.")] public void hasSameDoiButIsDifferentPublication_130() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "D3" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as different publications: Virta publication has type code E1, names differ.")] public void hasSameDoiButIsDifferentPublication_140() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name456", TypeCode = "E1" }; - Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.True(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } [Fact(DisplayName = "Virta and ORCID publication have the same DOI, they are considered as the same publications: Virta publication has type code E1, both have the same name.")] public void hasSameDoiButIsDifferentPublication_150() { DuplicateHandlerService duplicateHandlerService = new(); - DimOrcidPublication dimOrcidPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; + DimProfileOnlyPublication dimProfileOnlyPublication = new() { DoiHandle = "doi123", PublicationName = "name123" }; ProfileEditorPublication profileEditorPublication = new() { Doi = "doi123", PublicationName = "name123", TypeCode = "E1" }; - Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimOrcidPublication.PublicationName, profileEditorPublication)); + Assert.False(duplicateHandlerService.HasSameDoiButIsDifferentPublication(dimProfileOnlyPublication.PublicationName, profileEditorPublication)); } @@ -305,19 +305,19 @@ public void addPublicationToProfileEditorData_020() // Create ProfileDataRaw for ORCID publication 1. The same DOI and name as in Virta publication. ProfileDataFromSql profileDataOrcid1 = new() { - DimOrcidPublication_PublicationId = "publicationId456", - DimOrcidPublication_Doi = "doi123", - DimOrcidPublication_PublicationName = "name123", - DimFieldDisplaySettings_FieldIdentifier = Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID + DimProfileOnlyPublication_PublicationId = "publicationId456", + DimProfileOnlyPublication_Doi = "doi123", + DimProfileOnlyPublication_PublicationName = "name123", + DimFieldDisplaySettings_FieldIdentifier = Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY }; // Create ProfileDataRaw for ORCID publication 2. The same DOI as in Virta publication but different name. ProfileDataFromSql profileDataOrcid2 = new() { - DimOrcidPublication_PublicationId = "publicationId789", - DimOrcidPublication_Doi = "doi123", - DimOrcidPublication_PublicationName = "name456", - DimFieldDisplaySettings_FieldIdentifier = Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID + DimProfileOnlyPublication_PublicationId = "publicationId789", + DimProfileOnlyPublication_Doi = "doi123", + DimProfileOnlyPublication_PublicationName = "name456", + DimFieldDisplaySettings_FieldIdentifier = Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY }; // Create empty list of publications @@ -367,5 +367,5 @@ public void testPublicationYearHandling() // Publication year null Assert.Null(duplicateHandlerService.HandlePublicationYear(null)); } - } + } } \ No newline at end of file diff --git a/aspnetcore/src/api.Tests/Services_Tests/TtvSqlServiceTest.cs b/aspnetcore/src/api.Tests/Services_Tests/TtvSqlServiceTest.cs index d7bf3805..15a01060 100644 --- a/aspnetcore/src/api.Tests/Services_Tests/TtvSqlServiceTest.cs +++ b/aspnetcore/src/api.Tests/Services_Tests/TtvSqlServiceTest.cs @@ -1,14 +1,14 @@ -using Xunit; -using api.Services; -using api.Models.Common; -using api.Models.Ttv; +using Xunit; +using api.Services; +using api.Models.Common; +using api.Models.Ttv; using api.Models.ProfileEditor.Items; using System; using System.Collections.Generic; -namespace api.Tests -{ - [Collection("Get SQL query from TtvSqlService")] +namespace api.Tests +{ + [Collection("Get SQL query from TtvSqlService")] public class TtvSqlServiceTests { public FactFieldValue GetFactFieldValueForTest() @@ -27,7 +27,7 @@ public FactFieldValue GetFactFieldValueForTest() DimIdentifierlessDataId = -1, DimKeywordId = -1, DimNameId = -1, - DimOrcidPublicationId = -1, + DimProfileOnlyPublicationId = -1, DimPidId = -1, DimPidIdOrcidPutCode = -1, DimPublicationId = -1, @@ -38,7 +38,8 @@ public FactFieldValue GetFactFieldValueForTest() DimResearcherToResearchCommunityId = -1, DimTelephoneNumberId = -1, DimUserProfileId = -1, - DimWebLinkId = -1 + DimWebLinkId = -1, + DimReferencedataActorRoleId = -1 }; } @@ -137,13 +138,13 @@ public void getFactFieldValuesFKColumnNameFromFieldIdentifier_dim_publication_id ); } - [Fact(DisplayName = "Get FactFieldValues FK column name - dim_orcid_publication_id")] - public void getFactFieldValuesFKColumnNameFromFieldIdentifier_dim_orcid_publication_id() + [Fact(DisplayName = "Get FactFieldValues FK column name - dim_profile_only_publication_id")] + public void getFactFieldValuesFKColumnNameFromFieldIdentifier_dim_profile_only_publication_id() { TtvSqlService ttvSqlService = new(); // Web link Assert.Equal( - "dim_orcid_publication_id", ttvSqlService.GetFactFieldValuesFKColumnNameFromFieldIdentifier(Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID) + "dim_profile_only_publication_id", ttvSqlService.GetFactFieldValuesFKColumnNameFromFieldIdentifier(Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY) ); } @@ -346,13 +347,13 @@ public void Test_getSqlQuery_Delete_FactFieldValues_related_name() Assert.Equal(expectedSqlString, actualSqlString); } - [Fact(DisplayName = "Get SQL query for deleting FactFieldValues related data, ORCID publication")] - public void Test_getSqlQuery_Delete_FactFieldValues_related_ORCID_publication() + [Fact(DisplayName = "Get SQL query for deleting FactFieldValues related data, profile only publication")] + public void Test_getSqlQuery_Delete_FactFieldValues_related_profile_only_publication() { TtvSqlService ttvSqlService = new(); List ids = new() { 102, 103, 104 }; - string expectedSqlString = "DELETE FROM dim_orcid_publication WHERE id IN (102,103,104)"; - string actualSqlString = ttvSqlService.GetSqlQuery_Delete_DimOrcidPublications(ids); + string expectedSqlString = "DELETE FROM dim_profile_only_publication WHERE id IN (102,103,104)"; + string actualSqlString = ttvSqlService.GetSqlQuery_Delete_DimProfileOnlyPublications(ids); Assert.Equal(expectedSqlString, actualSqlString); } @@ -519,5 +520,5 @@ FROM fact_field_values AS ffv string actualSqlString = ttvSqlService.GetSqlQuery_Select_CountPublishedItemsInUserprofile(335577); Assert.Equal(expectedSqlString, actualSqlString); } - } + } } \ No newline at end of file diff --git a/aspnetcore/src/api.Tests/Services_Tests/UserProfileServiceTest.cs b/aspnetcore/src/api.Tests/Services_Tests/UserProfileServiceTest.cs index 3f8541f3..f464d0f4 100644 --- a/aspnetcore/src/api.Tests/Services_Tests/UserProfileServiceTest.cs +++ b/aspnetcore/src/api.Tests/Services_Tests/UserProfileServiceTest.cs @@ -1,18 +1,23 @@ -using Xunit; +using Xunit; using api.Services; using api.Models.Common; +using api.Models.Ttv; +using System.Collections.Generic; +using System; -namespace api.Tests -{ - [Collection("User profile service tests")] +namespace api.Tests +{ + [Collection("User profile service tests")] public class UserProfileServiceTests { [Fact(DisplayName = "Get FieldIdentifiers")] public void getFieldIdentifiers_01() { - var userProfileService = new UserProfileService(); - var fieldIdentifiers = userProfileService.GetFieldIdentifiers(); - + // Arrange + UserProfileService userProfileService = new UserProfileService(); + // Act + List fieldIdentifiers = userProfileService.GetFieldIdentifiers(); + // Assert Assert.Equal(16, fieldIdentifiers.Count); Assert.Contains(Constants.FieldIdentifiers.PERSON_EMAIL_ADDRESS, fieldIdentifiers); Assert.Contains(Constants.FieldIdentifiers.PERSON_EXTERNAL_IDENTIFIER, fieldIdentifiers); @@ -26,10 +31,174 @@ public void getFieldIdentifiers_01() Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_AFFILIATION, fieldIdentifiers); Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_EDUCATION, fieldIdentifiers); Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_PUBLICATION, fieldIdentifiers); - Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID, fieldIdentifiers); + Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY, fieldIdentifiers); Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_FUNDING_DECISION, fieldIdentifiers); Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_RESEARCH_DATASET, fieldIdentifiers); Assert.Contains(Constants.FieldIdentifiers.ACTIVITY_RESEARCH_ACTIVITY, fieldIdentifiers); } - } + + [Fact(DisplayName = "CanDeleteFactFieldValueRelatedData returns true")] + public void canDeleteFactFieldValueRelatedData_01() + { + // Arrange + DataSourceHelperService dataSourceHelperService = new DataSourceHelperService(); + dataSourceHelperService.DimRegisteredDataSourceId_ORCID = 12345; + UserProfileService userProfileService = new UserProfileService(dataSourceHelperService:dataSourceHelperService); + FactFieldValue ffv = new() + { + DimRegisteredDataSourceId = 12345 // Registered data source is the same as DimRegisteredDataSourceId_ORCID + }; + // Act + bool actualCanDeleteFactFieldValueRelatedData = userProfileService.CanDeleteFactFieldValueRelatedData(ffv); + // Assert + Assert.True(actualCanDeleteFactFieldValueRelatedData); + } + + [Fact(DisplayName = "CanDeleteFactFieldValueRelatedData returns false")] + public void canDeleteFactFieldValueRelatedData_02() + { + // Arrange + DataSourceHelperService dataSourceHelperService = new DataSourceHelperService(); + dataSourceHelperService.DimRegisteredDataSourceId_ORCID = 12345; + UserProfileService userProfileService = new UserProfileService(dataSourceHelperService: dataSourceHelperService); + FactFieldValue ffv = new() + { + DimRegisteredDataSourceId = 54321 // Registered data source is different from DimRegisteredDataSourceId_ORCID + }; + // Act + bool actualCanDeleteFactFieldValueRelatedData = userProfileService.CanDeleteFactFieldValueRelatedData(ffv); + // Assert + Assert.False(actualCanDeleteFactFieldValueRelatedData); + } + + [Fact(DisplayName = "Get new DimKnownPerson")] + public void getDimKnownPerson_01() + { + // Arrange + DataSourceHelperService dataSourceHelperService = new DataSourceHelperService(); + int orcidRegisteredDataSourceId = 789; + dataSourceHelperService.DimRegisteredDataSourceId_ORCID = orcidRegisteredDataSourceId; + UserProfileService userProfileService = new UserProfileService(dataSourceHelperService: dataSourceHelperService); + DateTime testDateTime = DateTime.Now; + string orcidId = "abcd-ef12-3456-7890"; + // Act + DimKnownPerson actualDimKnownPerson = userProfileService.GetNewDimKnownPerson(orcidId, testDateTime); + // Assert + Assert.Equal(orcidId, actualDimKnownPerson.SourceId); + Assert.Equal(Constants.SourceDescriptions.PROFILE_API, actualDimKnownPerson.SourceDescription); + Assert.Equal(orcidRegisteredDataSourceId, actualDimKnownPerson.DimRegisteredDataSourceId); + + } + + [Fact(DisplayName = "Get empty FactFieldValue")] + public void getEmptyFactFieldValue_01() + { + // Arrange + UtilityService utilityService = new UtilityService(); + UserProfileService userProfileService = new UserProfileService(utilityService: utilityService); + // Act + FactFieldValue actualFfv = userProfileService.GetEmptyFactFieldValue(); + // Assert + Assert.Equal(-1, actualFfv.DimUserProfileId); + Assert.Equal(-1, actualFfv.DimFieldDisplaySettingsId); + Assert.Equal(-1, actualFfv.DimNameId); + Assert.Equal(-1, actualFfv.DimWebLinkId); + Assert.Equal(-1, actualFfv.DimFundingDecisionId); + Assert.Equal(-1, actualFfv.DimPublicationId); + Assert.Equal(-1, actualFfv.DimPidId); + Assert.Equal(-1, actualFfv.DimPidIdOrcidPutCode); + Assert.Equal(-1, actualFfv.DimResearchActivityId); + Assert.Equal(-1, actualFfv.DimEventId); + Assert.Equal(-1, actualFfv.DimEducationId); + Assert.Equal(-1, actualFfv.DimCompetenceId); + Assert.Equal(-1, actualFfv.DimResearchCommunityId); + Assert.Equal(-1, actualFfv.DimTelephoneNumberId); + Assert.Equal(-1, actualFfv.DimEmailAddrressId); + Assert.Equal(-1, actualFfv.DimResearcherDescriptionId); + Assert.Equal(-1, actualFfv.DimIdentifierlessDataId); + Assert.Equal(-1, actualFfv.DimProfileOnlyPublicationId); + Assert.Equal(-1, actualFfv.DimProfileOnlyResearchActivityId); + Assert.Equal(-1, actualFfv.DimKeywordId); + Assert.Equal(-1, actualFfv.DimAffiliationId); + Assert.Equal(-1, actualFfv.DimResearcherToResearchCommunityId); + Assert.Equal(-1, actualFfv.DimResearchDatasetId); + Assert.Equal(-1, actualFfv.DimReferencedataFieldOfScienceId); + Assert.Equal(-1, actualFfv.DimReferencedataActorRoleId); + Assert.False(actualFfv.Show); + Assert.False(actualFfv.PrimaryValue); + Assert.Equal(Constants.SourceIdentifiers.PROFILE_API, actualFfv.SourceId); + Assert.Equal(Constants.SourceDescriptions.PROFILE_API, actualFfv.SourceDescription); + } + + [Fact(DisplayName = "Get empty DimProfileOnlyPublication")] + public void getEmptyDimProfileOnlyPublication_01() + { + // Arrange + UserProfileService userProfileService = new UserProfileService(); + // Act + DimProfileOnlyPublication actualDimProfileOnlyPublication = userProfileService.GetEmptyDimProfileOnlyPublication(); + // Assert + Assert.Equal(-1, actualDimProfileOnlyPublication.DimKnownPersonId); + Assert.Equal(-1, actualDimProfileOnlyPublication.DimRegisteredDataSourceId); + Assert.Null(actualDimProfileOnlyPublication.DimProfileOnlyPublicationId); + Assert.Equal(-1, actualDimProfileOnlyPublication.ParentTypeClassificationCode); + Assert.Equal(-1, actualDimProfileOnlyPublication.TypeClassificationCode); + Assert.Equal(-1, actualDimProfileOnlyPublication.PublicationFormatCode); + Assert.Equal(-1, actualDimProfileOnlyPublication.TargetAudienceCode); + Assert.Null(actualDimProfileOnlyPublication.OrcidWorkType); + Assert.Equal("", actualDimProfileOnlyPublication.PublicationName); + Assert.Null(actualDimProfileOnlyPublication.ConferenceName); + Assert.Null(actualDimProfileOnlyPublication.ShortDescription); + Assert.Null(actualDimProfileOnlyPublication.PublicationYear); + Assert.Equal("", actualDimProfileOnlyPublication.PublicationId); + Assert.Equal("", actualDimProfileOnlyPublication.AuthorsText); + Assert.Null(actualDimProfileOnlyPublication.NumberOfAuthors); + Assert.Null(actualDimProfileOnlyPublication.PageNumberText); + Assert.Null(actualDimProfileOnlyPublication.ArticleNumberText); + Assert.Null(actualDimProfileOnlyPublication.IssueNumber); + Assert.Null(actualDimProfileOnlyPublication.Volume); + Assert.Null(actualDimProfileOnlyPublication.PublicationCountryCode); + Assert.Null(actualDimProfileOnlyPublication.PublisherName); + Assert.Null(actualDimProfileOnlyPublication.PublisherLocation); + Assert.Null(actualDimProfileOnlyPublication.ParentPublicationName); + Assert.Null(actualDimProfileOnlyPublication.ParentPublicationEditors); + Assert.Null(actualDimProfileOnlyPublication.LicenseCode); + Assert.Equal(-1, actualDimProfileOnlyPublication.LanguageCode); + Assert.Null(actualDimProfileOnlyPublication.OpenAccessCode); + Assert.Null(actualDimProfileOnlyPublication.OriginalPublicationId); + Assert.Null(actualDimProfileOnlyPublication.PeerReviewed); + Assert.Null(actualDimProfileOnlyPublication.Report); + Assert.Null(actualDimProfileOnlyPublication.ThesisTypeCode); + Assert.Null(actualDimProfileOnlyPublication.DoiHandle); + Assert.Equal(Constants.SourceIdentifiers.PROFILE_API, actualDimProfileOnlyPublication.SourceId); + Assert.Equal(Constants.SourceDescriptions.PROFILE_API, actualDimProfileOnlyPublication.SourceDescription); + } + + [Fact(DisplayName = "Get empty DimPid")] + public void getEmptyDimPid_01() + { + // Arrange + UtilityService utilityService = new UtilityService(); + UserProfileService userProfileService = new UserProfileService(utilityService: utilityService); + // Act + DimPid actualDimPid = userProfileService.GetEmptyDimPid(); + // Assert + Assert.Equal("", actualDimPid.PidContent); + Assert.Equal("", actualDimPid.PidType); + Assert.Equal(-1, actualDimPid.DimOrganizationId); + Assert.Equal(-1, actualDimPid.DimKnownPersonId); + Assert.Equal(-1, actualDimPid.DimPublicationId); + Assert.Equal(-1, actualDimPid.DimServiceId); + Assert.Equal(-1, actualDimPid.DimInfrastructureId); + Assert.Equal(-1, actualDimPid.DimPublicationChannelId); + Assert.Equal(-1, actualDimPid.DimResearchDatasetId); + Assert.Equal(-1, actualDimPid.DimFundingDecisionId); + Assert.Equal(-1, actualDimPid.DimResearchDataCatalogId); + Assert.Equal(-1, actualDimPid.DimResearchActivityId); + Assert.Equal(-1, actualDimPid.DimEventId); + Assert.Equal(-1, actualDimPid.DimProfileOnlyPublicationId); + Assert.Equal(Constants.SourceIdentifiers.PROFILE_API, actualDimPid.SourceId); + Assert.Equal(Constants.SourceDescriptions.PROFILE_API, actualDimPid.SourceDescription); + } + } } \ No newline at end of file diff --git a/aspnetcore/src/api/Controllers/AdminController.cs b/aspnetcore/src/api/Controllers/AdminController.cs index dcebc44d..a5dc4b9a 100644 --- a/aspnetcore/src/api/Controllers/AdminController.cs +++ b/aspnetcore/src/api/Controllers/AdminController.cs @@ -10,7 +10,7 @@ using api.Models.Ttv; using api.Models.Log; -namespace api.Controllers +namespace api.Controllers { /* * AdminController implements API for administration commands. @@ -117,9 +117,9 @@ await _taskQueue.QueueBackgroundWorkItemAsync(async token => /// /// Admin: Unregister webhook for a single user profile. /// - /// [HttpPost] + [HttpPost] [Route("/[controller]/orcidwebhook/unregister/single/{webhookOrcidId}")] - public async Task UnegisterOrcidWebhookForSingleUserprofile(string webhookOrcidId) + public async Task UnregisterOrcidWebhookForSingleUserprofile(string webhookOrcidId) { // Validate request data if (!ModelState.IsValid) diff --git a/aspnetcore/src/api/Controllers/OrcidController.cs b/aspnetcore/src/api/Controllers/OrcidController.cs index 0b8e882d..bd2944f5 100644 --- a/aspnetcore/src/api/Controllers/OrcidController.cs +++ b/aspnetcore/src/api/Controllers/OrcidController.cs @@ -1,6 +1,6 @@ -using api.Services; -using api.Models.Api; -using api.Models.Orcid; +using api.Services; +using api.Models.Api; +using api.Models.Orcid; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; @@ -9,6 +9,7 @@ using System; using Microsoft.AspNetCore.Hosting; using api.Models.Log; +using Microsoft.Extensions.Caching.Memory; namespace api.Controllers { @@ -26,13 +27,15 @@ public class OrcidController : TtvControllerBase private readonly ITokenService _tokenService; private readonly ILogger _logger; private readonly IWebHostEnvironment _webHostEnvironment; + private readonly IMemoryCache _cache; public OrcidController(IUserProfileService userProfileService, IOrcidApiService orcidApiService, IOrcidImportService orcidImportService, ILogger logger, ITokenService tokenService, - IWebHostEnvironment webHostEnvironment) + IWebHostEnvironment webHostEnvironment, + IMemoryCache memoryCache) { _userProfileService = userProfileService; _orcidApiService = orcidApiService; @@ -40,6 +43,7 @@ public OrcidController(IUserProfileService userProfileService, _tokenService = tokenService; _logger = logger; _webHostEnvironment = webHostEnvironment; + _cache = memoryCache; } /// @@ -47,24 +51,20 @@ public OrcidController(IUserProfileService userProfileService, /// [HttpGet] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] - // TODO: Currently adding and updating ORCID data works, but detecting deleted ORCID data and deleting them is TTV database is not implemented. public async Task Get() { // Get ORCID id. string orcidId = this.GetOrcidId(); - // Log request. - //_logger.LogInformation(this.GetLogPrefix() + " get ORCID data request"); + // Get userprofile id + int userprofileId = await _userProfileService.GetUserprofileId(orcidId); // Check that userprofile exists. - if (!await _userProfileService.UserprofileExistsForOrcidId(orcidId: GetOrcidId())) + if (userprofileId < 1) { return Ok(new ApiResponse(success: false, reason: "profile not found")); } - // Get userprofile id - int userprofileId = await _userProfileService.GetUserprofileId(orcidId); - // Get ORCID record from ORCID member or public API. // If environment is not "Production" and user access token has claim "use_orcid_public_api", // then the record is requested from public API. @@ -83,6 +83,7 @@ public async Task Get() action: LogContent.Action.ORCID_RECORD_GET_PUBLIC_API, state: LogContent.ActionState.START)); + // Get ORCID record from ORCID public API orcidRecordJson = await _orcidApiService.GetRecordFromPublicApi(orcidId); _logger.LogInformation( @@ -158,6 +159,7 @@ public async Task Get() action: LogContent.Action.ORCID_RECORD_GET_MEMBER_API, state: LogContent.ActionState.START)); + // Get ORCID record from ORCID member API orcidRecordJson = await _orcidApiService.GetRecordFromMemberApi(orcidId, orcidTokens.AccessToken); _logger.LogInformation( @@ -214,6 +216,9 @@ public async Task Get() return Ok(new ApiResponse(success: false)); } + // Remove cached profile data response. Cache key is ORCID ID. + _cache.Remove(orcidId); + return Ok(new ApiResponse(success: true)); } } diff --git a/aspnetcore/src/api/Controllers/WebhookController.cs b/aspnetcore/src/api/Controllers/WebhookController.cs index 215f85ae..3acbcd66 100644 --- a/aspnetcore/src/api/Controllers/WebhookController.cs +++ b/aspnetcore/src/api/Controllers/WebhookController.cs @@ -4,9 +4,9 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using System; -using api.Models.Api; -using api.Models.Orcid; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Caching.Memory; +using api.Models.Log; namespace api.Controllers { @@ -25,16 +25,25 @@ public class WebhookController : ControllerBase private readonly ILogger _logger; private readonly IBackgroundTaskQueue _taskQueue; private readonly IServiceScopeFactory _serviceScopeFactory; + private readonly IElasticsearchService _elasticsearchService; + private readonly IBackgroundProfiledata _backgroundProfiledata; + private readonly IMemoryCache _cache; public WebhookController(IUserProfileService userProfileService, ILogger logger, IBackgroundTaskQueue taskQueue, - IServiceScopeFactory serviceScopeFactory) + IServiceScopeFactory serviceScopeFactory, + IElasticsearchService elasticsearchService, + IBackgroundProfiledata backgroundProfiledata, + IMemoryCache memoryCache) { _userProfileService = userProfileService; _logger = logger; _taskQueue = taskQueue; _serviceScopeFactory = serviceScopeFactory; + _elasticsearchService = elasticsearchService; + _backgroundProfiledata = backgroundProfiledata; + _cache = memoryCache; } @@ -46,9 +55,9 @@ public WebhookController(IUserProfileService userProfileService, [Route("api/webhook/orcid/{webhookOrcidId}")] public async Task HandleOrcidWebhook(string webhookOrcidId) { - string logPrefix = "ORCID webhook: "; string orcidAccessToken = ""; int dimUserprofileId = -1; + LogUserIdentification logUserIdentification = new(orcid: webhookOrcidId); // Validate request data if (!ModelState.IsValid) @@ -56,24 +65,50 @@ public async Task HandleOrcidWebhook(string webhookOrcidId) return BadRequest(); } - _logger.LogInformation($"{logPrefix}received for {webhookOrcidId}"); + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_WEBHOOK_RECEIVED, + state: LogContent.ActionState.START)); // Check that userprofile exists. DimUserProfile dimUserProfile = await _userProfileService.GetUserprofile(orcidId: webhookOrcidId); if (dimUserProfile == null) { - _logger.LogError($"{logPrefix}user profile not found: {webhookOrcidId}"); + _logger.LogError( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_WEBHOOK_RECEIVED, + error: true, + message: LogContent.ErrorMessage.USER_PROFILE_NOT_FOUND, + state: LogContent.ActionState.START)); + return NoContent(); } + // Remove cached profile data response. Cache key is ORCID ID. + _cache.Remove(webhookOrcidId); + // Store values to be used in background task. orcidAccessToken = dimUserProfile.OrcidAccessToken; dimUserprofileId = dimUserProfile.Id; + // Check if the profile is publihed. Published profile should be updated after ORCID import + bool isUserprofilePublished = await _userProfileService.IsUserprofilePublished(dimUserprofileId); + // Get ORCID data in a background task. await _taskQueue.QueueBackgroundWorkItemAsync(async token => { - _logger.LogInformation($"{logPrefix}background update for {webhookOrcidId} started {DateTime.UtcNow}"); + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.BACKGROUND_UPDATE, + state: LogContent.ActionState.START)); + + bool importSuccess = false; // Create service scope and get required services. // Do not use services from controller scope in a background task. @@ -85,12 +120,32 @@ await _taskQueue.QueueBackgroundWorkItemAsync(async token => string orcidRecordJson = ""; try { + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_RECORD_GET_MEMBER_API, + state: LogContent.ActionState.START)); + orcidRecordJson = await localOrcidApiService.GetRecordFromMemberApi(webhookOrcidId, orcidAccessToken); - _logger.LogInformation($"{logPrefix}background get record for {webhookOrcidId} OK"); + + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_RECORD_GET_MEMBER_API, + state: LogContent.ActionState.COMPLETE)); } catch (Exception ex) { - _logger.LogError($"{logPrefix}background get record for {webhookOrcidId} failed: {ex}"); + _logger.LogError( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_RECORD_GET_MEMBER_API, + error: true, + message: ex.ToString(), + state: LogContent.ActionState.FAILED)); } // Import record json into userprofile @@ -98,16 +153,68 @@ await _taskQueue.QueueBackgroundWorkItemAsync(async token => { try { - await localOrcidImportService.ImportOrcidRecordJsonIntoUserProfile(dimUserprofileId, orcidRecordJson); - _logger.LogInformation($"{logPrefix}background import record for {webhookOrcidId} to userprofile OK"); + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_RECORD_IMPORT, + state: LogContent.ActionState.START)); + + importSuccess = await localOrcidImportService.ImportOrcidRecordJsonIntoUserProfile(dimUserprofileId, orcidRecordJson); + + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_RECORD_IMPORT, + state: LogContent.ActionState.COMPLETE)); } catch (Exception ex) { - _logger.LogError($"{logPrefix}background import record for {webhookOrcidId} to userprofile failed: {ex}"); + _logger.LogError( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ORCID_RECORD_IMPORT, + error: true, + message: ex.ToString(), + state: LogContent.ActionState.FAILED)); } } - _logger.LogInformation($"{logPrefix}background update for {webhookOrcidId} ended {DateTime.UtcNow}"); + // If user profile is published, then after successful ORCID import update Elasticsearch index + if (importSuccess && isUserprofilePublished && _elasticsearchService.IsElasticsearchSyncEnabled()) + { + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ELASTICSEARCH_UPDATE, + state: LogContent.ActionState.START)); + + // Get Elasticsearch person entry from profile data. + Models.Elasticsearch.ElasticsearchPerson person = + await _backgroundProfiledata.GetProfiledataForElasticsearch( + orcidId: webhookOrcidId, + userprofileId: dimUserprofileId, + logUserIdentification: logUserIdentification); + // Update Elasticsearch person index. + await _elasticsearchService.UpdateEntryInElasticsearchPersonIndex(webhookOrcidId, person, logUserIdentification); + + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.ELASTICSEARCH_UPDATE, + state: LogContent.ActionState.COMPLETE)); + } + + _logger.LogInformation( + LogContent.MESSAGE_TEMPLATE, + logUserIdentification, + new LogApiInfo( + action: LogContent.Action.BACKGROUND_UPDATE, + state: LogContent.ActionState.COMPLETE)); }); return NoContent(); diff --git a/aspnetcore/src/api/Models/Common/Constants.cs b/aspnetcore/src/api/Models/Common/Constants.cs index 0654caf2..0f42eea2 100644 --- a/aspnetcore/src/api/Models/Common/Constants.cs +++ b/aspnetcore/src/api/Models/Common/Constants.cs @@ -21,7 +21,7 @@ public static class FieldIdentifiers public const int ACTIVITY_AFFILIATION = 300; public const int ACTIVITY_EDUCATION = 400; public const int ACTIVITY_PUBLICATION = 500; - public const int ACTIVITY_PUBLICATION_ORCID = 550; + public const int ACTIVITY_PUBLICATION_PROFILE_ONLY = 550; public const int ACTIVITY_RESEARCH_DATASET = 600; public const int ACTIVITY_INFRASTRUCTURE = 700; public const int ACTIVITY_FUNDING_DECISION = 800; diff --git a/aspnetcore/src/api/Models/Orcid/OrcidImportHelper.cs b/aspnetcore/src/api/Models/Orcid/OrcidImportHelper.cs new file mode 100644 index 00000000..0bf7d4d6 --- /dev/null +++ b/aspnetcore/src/api/Models/Orcid/OrcidImportHelper.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace api.Models.Orcid +{ + public class OrcidImportHelper { + public OrcidImportHelper() + { + dimNameIds = new(); + dimWebLinkIds = new(); + dimResearcherDescriptionIds = new(); + dimEmailAddressIds = new(); + dimKeywordIds = new(); + dimPidIds = new(); + dimAffiliationIds = new(); + dimEducationIds = new(); + dimPublicationIds = new(); + } + + public List dimNameIds { get; set; } + public List dimWebLinkIds { get; set; } + public List dimResearcherDescriptionIds { get; set; } + public List dimEmailAddressIds { get; set; } + public List dimKeywordIds { get; set; } + public List dimPidIds { get; set; } + public List dimAffiliationIds { get; set; } + public List dimEducationIds { get; set; } + public List dimPublicationIds { get; set; } + } +} \ No newline at end of file diff --git a/aspnetcore/src/api/Models/ProfileEditor/ProfileDataFromSql.cs b/aspnetcore/src/api/Models/ProfileEditor/ProfileDataFromSql.cs index bb1d9c97..3392fb01 100644 --- a/aspnetcore/src/api/Models/ProfileEditor/ProfileDataFromSql.cs +++ b/aspnetcore/src/api/Models/ProfileEditor/ProfileDataFromSql.cs @@ -27,7 +27,7 @@ public ProfileDataFromSql() public int FactFieldValues_DimIdentifierlessDataId { get; set; } public int FactFieldValues_DimEducationId { get; set; } public int FactFieldValues_DimPublicationId { get; set; } - public int FactFieldValues_DimOrcidPublicationId { get; set; } + public int FactFieldValues_DimProfileOnlyPublicationId { get; set; } public int FactFieldValues_DimResearchActivityId { get; set; } public int FactFieldValues_DimFundingDecisionId { get; set; } public int FactFieldValues_DimResearchDatasetId { get; set; } @@ -133,11 +133,11 @@ public ProfileDataFromSql() public string DimPublication_JournalName { get; set; } public string DimPublication_ConferenceName { get; set; } public string DimPublication_ParentPublicationName { get; set; } - // DimOrcidPublication - public string DimOrcidPublication_PublicationId { get; set; } - public string DimOrcidPublication_PublicationName { get; set; } - public int DimOrcidPublication_PublicationYear { get; set; } - public string DimOrcidPublication_Doi { get; set; } + // DimProfileOnlyPublication + public string DimProfileOnlyPublication_PublicationId { get; set; } + public string DimProfileOnlyPublication_PublicationName { get; set; } + public int DimProfileOnlyPublication_PublicationYear { get; set; } + public string DimProfileOnlyPublication_Doi { get; set; } // DimResearchActivity public string DimResearchActivity_NameFi { get; set; } public string DimResearchActivity_NameEn { get; set; } diff --git a/aspnetcore/src/api/Models/SerilogHttpSink/BasicAuthenticatedHttpClient.cs b/aspnetcore/src/api/Models/SerilogHttpSink/BasicAuthenticatedHttpClient.cs new file mode 100644 index 00000000..61bb4731 --- /dev/null +++ b/aspnetcore/src/api/Models/SerilogHttpSink/BasicAuthenticatedHttpClient.cs @@ -0,0 +1,50 @@ +using Microsoft.Extensions.Configuration; +using Serilog.Sinks.Http; +using System; +using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; + +namespace Mydatalogging; + +/* + * Custom HttpClient to be used with Serilog HTTP sink. + * This client enables use of HTTP basic authentication. + * Source: + * https://github.com/FantasticFiasco/serilog-sinks-http/wiki/Custom-HTTP-client + */ +public class BasicAuthenticatedHttpClient : IHttpClient +{ + private readonly HttpClient httpClient; + + public BasicAuthenticatedHttpClient() + { + httpClient = new HttpClient(); + } + + public void Configure(IConfiguration configuration) + { + var username = configuration["LogServer:username"]; + var password = configuration["LogServer:password"]; + + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( + "Basic", + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"))); + } + + public async Task PostAsync(string requestUri, Stream contentStream) + { + using var content = new StreamContent(contentStream); + content.Headers.Add("Content-Type", "application/json"); + + var response = await httpClient + .PostAsync(requestUri, content) + .ConfigureAwait(false); + + return response; + } + + public void Dispose() => httpClient?.Dispose(); +} \ No newline at end of file diff --git a/aspnetcore/src/api/Models/StructuredLog/LogContent.cs b/aspnetcore/src/api/Models/StructuredLog/LogContent.cs index bba6e309..61ddb730 100644 --- a/aspnetcore/src/api/Models/StructuredLog/LogContent.cs +++ b/aspnetcore/src/api/Models/StructuredLog/LogContent.cs @@ -12,6 +12,7 @@ public static class Action public const string ADMIN_WEBHOOK_ORCID_UNREGISTER_ALL = "Admin: ORCID webhook unregister all"; public const string ADMIN_ELASTICSEARCH_PROFILE_DELETE = "Admin: Elasticsearch: profile: delete"; public const string ADMIN_ELASTICSEARCH_PROFILE_UPDATE = "Admin: Elasticsearch: profile: update"; + public const string BACKGROUND_UPDATE = "Background: update"; public const string ELASTICSEARCH_DELETE = "Elasticsearch: profile: delete"; public const string ELASTICSEARCH_UPDATE = "Elasticsearch: profile: update"; public const string KEYCLOAK_ACCOUNT_DELETE = "Keycloak: account delete"; @@ -31,6 +32,7 @@ public static class Action public const string ORCID_RECORD_IMPORT = "ORCID: record: import"; public const string ORCID_WEBHOOK_REGISTER = "ORCID: webhook: register"; public const string ORCID_WEBHOOK_UNREGISTER = "ORCID: webhook: unregister"; + public const string ORCID_WEBHOOK_RECEIVED = "ORCID: webhook: received"; } public static class ActionState @@ -39,5 +41,10 @@ public static class ActionState public const string COMPLETE = "complete"; public const string FAILED = "failed"; } + + public static class ErrorMessage + { + public const string USER_PROFILE_NOT_FOUND = "user profile not found"; + } } } diff --git a/aspnetcore/src/api/Models/Ttv/BrCallProgrammeDimCallProgramme.cs b/aspnetcore/src/api/Models/Ttv/BrCallProgrammeDimCallProgramme.cs deleted file mode 100644 index c74384ff..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrCallProgrammeDimCallProgramme.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrCallProgrammeDimCallProgramme - { - public int DimCallProgrammeId { get; set; } - public int DimCallProgrammeId2 { get; set; } - - public virtual DimCallProgramme DimCallProgramme { get; set; } - public virtual DimCallProgramme DimCallProgrammeId2Navigation { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrDimReferencedataDimCallProgramme.cs b/aspnetcore/src/api/Models/Ttv/BrDimReferencedataDimCallProgramme.cs deleted file mode 100644 index 4c70e959..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrDimReferencedataDimCallProgramme.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrDimReferencedataDimCallProgramme - { - public int DimCallProgrammeId { get; set; } - public int DimReferencedataId { get; set; } - - public virtual DimCallProgramme DimCallProgramme { get; set; } - public virtual DimReferencedatum DimReferencedata { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrEsfriDimInfrastructure.cs b/aspnetcore/src/api/Models/Ttv/BrEsfriDimInfrastructure.cs deleted file mode 100644 index 8c0581a3..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrEsfriDimInfrastructure.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrEsfriDimInfrastructure - { - public int DimEsfriId { get; set; } - public int DimInfrastructureId { get; set; } - - public virtual DimEsfri DimEsfri { get; set; } - public virtual DimInfrastructure DimInfrastructure { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrFieldDisplaySettingsDimRegisteredDataSource.cs b/aspnetcore/src/api/Models/Ttv/BrFieldDisplaySettingsDimRegisteredDataSource.cs deleted file mode 100644 index 649ee996..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrFieldDisplaySettingsDimRegisteredDataSource.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrFieldDisplaySettingsDimRegisteredDataSource - { - public int DimFieldDisplaySettingsId { get; set; } - public int DimRegisteredDataSourceId { get; set; } - - public virtual DimFieldDisplaySetting DimFieldDisplaySettings { get; set; } - public virtual DimRegisteredDataSource DimRegisteredDataSource { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrFieldOfArtDimPublication.cs b/aspnetcore/src/api/Models/Ttv/BrFieldOfArtDimPublication.cs deleted file mode 100644 index 47bdb28c..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrFieldOfArtDimPublication.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrFieldOfArtDimPublication - { - public int DimFieldOfArtId { get; set; } - public int DimPublicationId { get; set; } - - public virtual DimFieldOfArt DimFieldOfArt { get; set; } - public virtual DimPublication DimPublication { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrFieldOfEducationDimPublication.cs b/aspnetcore/src/api/Models/Ttv/BrFieldOfEducationDimPublication.cs deleted file mode 100644 index efefe238..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrFieldOfEducationDimPublication.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrFieldOfEducationDimPublication - { - public int DimFieldOfEducationId { get; set; } - public int DimPublicationId { get; set; } - - public virtual DimFieldOfEducation DimFieldOfEducation { get; set; } - public virtual DimPublication DimPublication { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimFundingDecision.cs b/aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimFundingDecision.cs deleted file mode 100644 index f8344ca4..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimFundingDecision.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrFieldOfScienceDimFundingDecision - { - public int DimFieldOfScienceId { get; set; } - public int DimFundingDecisionId { get; set; } - - public virtual DimFieldOfScience DimFieldOfScience { get; set; } - public virtual DimFundingDecision DimFundingDecision { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimPublication.cs b/aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimPublication.cs deleted file mode 100644 index e1c875b6..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrFieldOfScienceDimPublication.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrFieldOfScienceDimPublication - { - public int DimFieldOfScienceId { get; set; } - public int DimPublicationId { get; set; } - - public virtual DimFieldOfScience DimFieldOfScience { get; set; } - public virtual DimPublication DimPublication { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrFundingDecisionDimFieldOfArt.cs b/aspnetcore/src/api/Models/Ttv/BrFundingDecisionDimFieldOfArt.cs deleted file mode 100644 index 9aa6775c..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrFundingDecisionDimFieldOfArt.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrFundingDecisionDimFieldOfArt - { - public int DimFundingDecisionId { get; set; } - public int DimFieldOfArtId { get; set; } - - public virtual DimFieldOfArt DimFieldOfArt { get; set; } - public virtual DimFundingDecision DimFundingDecision { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrInfrastructureDimFieldOfScience.cs b/aspnetcore/src/api/Models/Ttv/BrInfrastructureDimFieldOfScience.cs deleted file mode 100644 index 8d784f88..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrInfrastructureDimFieldOfScience.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrInfrastructureDimFieldOfScience - { - public int DimInfrastructureId { get; set; } - public int DimFieldOfScienceId { get; set; } - - public virtual DimFieldOfScience DimFieldOfScience { get; set; } - public virtual DimInfrastructure DimInfrastructure { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrKeywordDimFundingDecision.cs b/aspnetcore/src/api/Models/Ttv/BrKeywordDimFundingDecision.cs deleted file mode 100644 index 491d2896..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrKeywordDimFundingDecision.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrKeywordDimFundingDecision - { - public int DimKeywordId { get; set; } - public int DimFundingDecisionId { get; set; } - - public virtual DimFundingDecision DimFundingDecision { get; set; } - public virtual DimKeyword DimKeyword { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrKeywordDimPublication.cs b/aspnetcore/src/api/Models/Ttv/BrKeywordDimPublication.cs deleted file mode 100644 index e3660747..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrKeywordDimPublication.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrKeywordDimPublication - { - public int DimKeywordId { get; set; } - public int DimPublicationId { get; set; } - - public virtual DimKeyword DimKeyword { get; set; } - public virtual DimPublication DimPublication { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrLanguageCodesForDataset.cs b/aspnetcore/src/api/Models/Ttv/BrLanguageCodesForDataset.cs deleted file mode 100644 index afb4d2a8..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrLanguageCodesForDataset.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrLanguageCodesForDataset - { - public int DimResearchDatasetId { get; set; } - public int DimReferencedataId { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrMerilDimInfrastructure.cs b/aspnetcore/src/api/Models/Ttv/BrMerilDimInfrastructure.cs deleted file mode 100644 index 716f2e95..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrMerilDimInfrastructure.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrMerilDimInfrastructure - { - public int DimMerilId { get; set; } - public int DimInfrastructureId { get; set; } - - public virtual DimInfrastructure DimInfrastructure { get; set; } - public virtual DimMeril DimMeril { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrOrganizationsFundCallProgramme.cs b/aspnetcore/src/api/Models/Ttv/BrOrganizationsFundCallProgramme.cs deleted file mode 100644 index f6daf6a2..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrOrganizationsFundCallProgramme.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrOrganizationsFundCallProgramme - { - public int DimOrganizationid { get; set; } - public int DimCallProgrammeid { get; set; } - - public virtual DimCallProgramme DimCallProgramme { get; set; } - public virtual DimOrganization DimOrganization { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrPredecessorOrganization.cs b/aspnetcore/src/api/Models/Ttv/BrPredecessorOrganization.cs deleted file mode 100644 index 8dee6ae2..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrPredecessorOrganization.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrPredecessorOrganization - { - public int DimOrganizationid { get; set; } - public int DimOrganizationid2 { get; set; } - - public virtual DimOrganization DimOrganization { get; set; } - public virtual DimOrganization DimOrganizationid2Navigation { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrPreviousFundingDecision.cs b/aspnetcore/src/api/Models/Ttv/BrPreviousFundingDecision.cs deleted file mode 100644 index 80614462..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrPreviousFundingDecision.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrPreviousFundingDecision - { - public int DimFundingDecisionFromId { get; set; } - public int DimFundingDecisionToId { get; set; } - - public virtual DimFundingDecision DimFundingDecisionFrom { get; set; } - public virtual DimFundingDecision DimFundingDecisionTo { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrRelatedFundingDecision.cs b/aspnetcore/src/api/Models/Ttv/BrRelatedFundingDecision.cs deleted file mode 100644 index 0a15f02e..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrRelatedFundingDecision.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrRelatedFundingDecision - { - public int DimFundingDecisionFromId { get; set; } - public int DimFundingDecisionToId { get; set; } - - public virtual DimFundingDecision DimFundingDecisionFrom { get; set; } - public virtual DimFundingDecision DimFundingDecisionTo { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrResearchDatasetDimKeyword.cs b/aspnetcore/src/api/Models/Ttv/BrResearchDatasetDimKeyword.cs deleted file mode 100644 index fa025d41..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrResearchDatasetDimKeyword.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrResearchDatasetDimKeyword - { - public int DimResearchDatasetId { get; set; } - public int DimKeywordId { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/BrResearcherToResearchCommunity.cs b/aspnetcore/src/api/Models/Ttv/BrResearcherToResearchCommunity.cs deleted file mode 100644 index 18243247..00000000 --- a/aspnetcore/src/api/Models/Ttv/BrResearcherToResearchCommunity.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class BrResearcherToResearchCommunity - { - public int DimResearchCommunityId { get; set; } - public int DimKnownPersonId { get; set; } - public int StartDate { get; set; } - public int EndDate { get; set; } - public string DescriptionFi { get; set; } - public string DescriptionEn { get; set; } - public string DescriptionSv { get; set; } - public string SourceId { get; set; } - public string SourceDescription { get; set; } - public DateTime? Created { get; set; } - public DateTime? Modified { get; set; } - public int DimRegisteredDataSourceId { get; set; } - - public virtual DimKnownPerson DimKnownPerson { get; set; } - public virtual DimRegisteredDataSource DimRegisteredDataSource { get; set; } - public virtual DimResearchCommunity DimResearchCommunity { get; set; } - public virtual DimDate EndDateNavigation { get; set; } - public virtual DimDate StartDateNavigation { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/DimAffiliation.cs b/aspnetcore/src/api/Models/Ttv/DimAffiliation.cs index 799b9a33..bb328f15 100644 --- a/aspnetcore/src/api/Models/Ttv/DimAffiliation.cs +++ b/aspnetcore/src/api/Models/Ttv/DimAffiliation.cs @@ -25,6 +25,7 @@ public DimAffiliation() public DateTime? Created { get; set; } public DateTime? Modified { get; set; } public int DimRegisteredDataSourceId { get; set; } + public string LocalIdentifier { get; set; } public virtual DimReferencedatum AffiliationTypeNavigation { get; set; } public virtual DimKnownPerson DimKnownPerson { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimCallProgramme.cs b/aspnetcore/src/api/Models/Ttv/DimCallProgramme.cs index 58065b51..3ac8ce5b 100644 --- a/aspnetcore/src/api/Models/Ttv/DimCallProgramme.cs +++ b/aspnetcore/src/api/Models/Ttv/DimCallProgramme.cs @@ -41,6 +41,9 @@ public DimCallProgramme() public string ContactInformation { get; set; } public bool? ContinuousApplicationPeriod { get; set; } public bool IsOpenCall { get; set; } + public string CallNameDetailsFi { get; set; } + public string CallNameDetailsEn { get; set; } + public string CallNameDetailsSv { get; set; } public virtual DimDate DimDateIdDueNavigation { get; set; } public virtual DimDate DimDateIdOpenNavigation { get; set; } @@ -53,4 +56,4 @@ public DimCallProgramme() public virtual ICollection DimOrganizations { get; set; } public virtual ICollection DimReferencedata { get; set; } } -} +} \ No newline at end of file diff --git a/aspnetcore/src/api/Models/Ttv/DimDate.cs b/aspnetcore/src/api/Models/Ttv/DimDate.cs index 83fe8bd3..1bb97f71 100644 --- a/aspnetcore/src/api/Models/Ttv/DimDate.cs +++ b/aspnetcore/src/api/Models/Ttv/DimDate.cs @@ -18,6 +18,8 @@ public DimDate() DimFundingDecisionDimDateIdApprovalNavigations = new HashSet(); DimFundingDecisionDimDateIdEndNavigations = new HashSet(); DimFundingDecisionDimDateIdStartNavigations = new HashSet(); + DimProfileOnlyResearchActivityDimDateIdEndNavigations = new HashSet(); + DimProfileOnlyResearchActivityDimDateIdStartNavigations = new HashSet(); DimResearchActivityDimEndDateNavigations = new HashSet(); DimResearchActivityDimStartDateNavigations = new HashSet(); DimResearcherToResearchCommunityEndDateNavigations = new HashSet(); @@ -47,6 +49,8 @@ public DimDate() public virtual ICollection DimFundingDecisionDimDateIdApprovalNavigations { get; set; } public virtual ICollection DimFundingDecisionDimDateIdEndNavigations { get; set; } public virtual ICollection DimFundingDecisionDimDateIdStartNavigations { get; set; } + public virtual ICollection DimProfileOnlyResearchActivityDimDateIdEndNavigations { get; set; } + public virtual ICollection DimProfileOnlyResearchActivityDimDateIdStartNavigations { get; set; } public virtual ICollection DimResearchActivityDimEndDateNavigations { get; set; } public virtual ICollection DimResearchActivityDimStartDateNavigations { get; set; } public virtual ICollection DimResearcherToResearchCommunityEndDateNavigations { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimEvent.cs b/aspnetcore/src/api/Models/Ttv/DimEvent.cs index ab3019e4..8f3d83e5 100644 --- a/aspnetcore/src/api/Models/Ttv/DimEvent.cs +++ b/aspnetcore/src/api/Models/Ttv/DimEvent.cs @@ -8,6 +8,7 @@ public partial class DimEvent public DimEvent() { DimPids = new HashSet(); + DimProfileOnlyResearchActivities = new HashSet(); DimResearchActivities = new HashSet(); FactFieldValues = new HashSet(); } @@ -32,6 +33,7 @@ public DimEvent() public virtual DimGeo DimGeoIdEventCountryNavigation { get; set; } public virtual DimRegisteredDataSource DimRegisteredDataSource { get; set; } public virtual ICollection DimPids { get; set; } + public virtual ICollection DimProfileOnlyResearchActivities { get; set; } public virtual ICollection DimResearchActivities { get; set; } public virtual ICollection FactFieldValues { get; set; } } diff --git a/aspnetcore/src/api/Models/Ttv/DimFieldOfScience.cs b/aspnetcore/src/api/Models/Ttv/DimFieldOfScience.cs deleted file mode 100644 index 53ed73dd..00000000 --- a/aspnetcore/src/api/Models/Ttv/DimFieldOfScience.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace api.Models.Ttv -{ - public partial class DimFieldOfScience - { - public int Id { get; set; } - public string FieldId { get; set; } - public string NameFi { get; set; } - public string NameEn { get; set; } - public string NameSv { get; set; } - public string SourceId { get; set; } - public string SourceDescription { get; set; } - public DateTime? Created { get; set; } - public DateTime? Modified { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/DimFieldOfScienceDimResearchActivity.cs b/aspnetcore/src/api/Models/Ttv/DimFieldOfScienceDimResearchActivity.cs deleted file mode 100644 index 90c51c29..00000000 --- a/aspnetcore/src/api/Models/Ttv/DimFieldOfScienceDimResearchActivity.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class DimFieldOfScienceDimResearchActivity - { - public int DimFieldOfScienceId { get; set; } - public int DimResearchActivityId { get; set; } - - public virtual DimFieldOfScience DimFieldOfScience { get; set; } - public virtual DimResearchActivity DimResearchActivity { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/DimGeo.cs b/aspnetcore/src/api/Models/Ttv/DimGeo.cs index 3e4e3395..d08865a6 100644 --- a/aspnetcore/src/api/Models/Ttv/DimGeo.cs +++ b/aspnetcore/src/api/Models/Ttv/DimGeo.cs @@ -9,6 +9,7 @@ public DimGeo() { DimEvents = new HashSet(); DimFundingDecisions = new HashSet(); + DimProfileOnlyResearchActivities = new HashSet(); DimResearchActivities = new HashSet(); FactContributions = new HashSet(); FactUpkeeps = new HashSet(); @@ -33,6 +34,7 @@ public DimGeo() public virtual ICollection DimEvents { get; set; } public virtual ICollection DimFundingDecisions { get; set; } + public virtual ICollection DimProfileOnlyResearchActivities { get; set; } public virtual ICollection DimResearchActivities { get; set; } public virtual ICollection FactContributions { get; set; } public virtual ICollection FactUpkeeps { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimKnownPerson.cs b/aspnetcore/src/api/Models/Ttv/DimKnownPerson.cs index 73d056c6..5f57f94e 100644 --- a/aspnetcore/src/api/Models/Ttv/DimKnownPerson.cs +++ b/aspnetcore/src/api/Models/Ttv/DimKnownPerson.cs @@ -12,8 +12,8 @@ public DimKnownPerson() DimEducations = new HashSet(); DimEmailAddrresses = new HashSet(); DimNames = new HashSet(); - DimOrcidPublications = new HashSet(); DimPids = new HashSet(); + DimProfileOnlyPublications = new HashSet(); DimResearcherDescriptions = new HashSet(); DimResearcherToResearchCommunities = new HashSet(); DimTelephoneNumbers = new HashSet(); @@ -36,8 +36,8 @@ public DimKnownPerson() public virtual ICollection DimEducations { get; set; } public virtual ICollection DimEmailAddrresses { get; set; } public virtual ICollection DimNames { get; set; } - public virtual ICollection DimOrcidPublications { get; set; } public virtual ICollection DimPids { get; set; } + public virtual ICollection DimProfileOnlyPublications { get; set; } public virtual ICollection DimResearcherDescriptions { get; set; } public virtual ICollection DimResearcherToResearchCommunities { get; set; } public virtual ICollection DimTelephoneNumbers { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimKnownPersonDimFieldOfScience.cs b/aspnetcore/src/api/Models/Ttv/DimKnownPersonDimFieldOfScience.cs deleted file mode 100644 index d5aced7d..00000000 --- a/aspnetcore/src/api/Models/Ttv/DimKnownPersonDimFieldOfScience.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -#nullable disable - -namespace api.Models.Ttv -{ - public partial class DimKnownPersonDimFieldOfScience - { - public int DimFieldOfScienceId { get; set; } - public int DimKnownPersonId { get; set; } - - public virtual DimFieldOfScience DimFieldOfScience { get; set; } - public virtual DimKnownPerson DimKnownPerson { get; set; } - } -} diff --git a/aspnetcore/src/api/Models/Ttv/DimOrganization.cs b/aspnetcore/src/api/Models/Ttv/DimOrganization.cs index 22901534..b1979b57 100644 --- a/aspnetcore/src/api/Models/Ttv/DimOrganization.cs +++ b/aspnetcore/src/api/Models/Ttv/DimOrganization.cs @@ -13,6 +13,7 @@ public DimOrganization() DimExternalServices = new HashSet(); DimFundingDecisions = new HashSet(); DimPids = new HashSet(); + DimProfileOnlyResearchActivities = new HashSet(); DimPurposes = new HashSet(); DimRegisteredDataSources = new HashSet(); DimResearchActivities = new HashSet(); @@ -65,6 +66,7 @@ public DimOrganization() public virtual ICollection DimExternalServices { get; set; } public virtual ICollection DimFundingDecisions { get; set; } public virtual ICollection DimPids { get; set; } + public virtual ICollection DimProfileOnlyResearchActivities { get; set; } public virtual ICollection DimPurposes { get; set; } public virtual ICollection DimRegisteredDataSources { get; set; } public virtual ICollection DimResearchActivities { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimPid.cs b/aspnetcore/src/api/Models/Ttv/DimPid.cs index 053c3754..5c75c2b0 100644 --- a/aspnetcore/src/api/Models/Ttv/DimPid.cs +++ b/aspnetcore/src/api/Models/Ttv/DimPid.cs @@ -25,7 +25,7 @@ public DimPid() public int DimResearchDataCatalogId { get; set; } public int DimResearchActivityId { get; set; } public int DimEventId { get; set; } - public int DimOrcidPublicationId { get; set; } + public int DimProfileOnlyPublicationId { get; set; } public string SourceId { get; set; } public string SourceDescription { get; set; } public DateTime? Created { get; set; } @@ -35,8 +35,8 @@ public DimPid() public virtual DimFundingDecision DimFundingDecision { get; set; } public virtual DimInfrastructure DimInfrastructure { get; set; } public virtual DimKnownPerson DimKnownPerson { get; set; } - public virtual DimOrcidPublication DimOrcidPublication { get; set; } public virtual DimOrganization DimOrganization { get; set; } + public virtual DimProfileOnlyPublication DimProfileOnlyPublication { get; set; } public virtual DimPublication DimPublication { get; set; } public virtual DimPublicationChannel DimPublicationChannel { get; set; } public virtual DimResearchActivity DimResearchActivity { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimOrcidPublication.cs b/aspnetcore/src/api/Models/Ttv/DimProfileOnlyPublication.cs similarity index 58% rename from aspnetcore/src/api/Models/Ttv/DimOrcidPublication.cs rename to aspnetcore/src/api/Models/Ttv/DimProfileOnlyPublication.cs index 5b7427f8..2bbe6148 100644 --- a/aspnetcore/src/api/Models/Ttv/DimOrcidPublication.cs +++ b/aspnetcore/src/api/Models/Ttv/DimProfileOnlyPublication.cs @@ -3,21 +3,33 @@ namespace api.Models.Ttv { - public partial class DimOrcidPublication + public partial class DimProfileOnlyPublication { - public DimOrcidPublication() + public DimProfileOnlyPublication() { DimPids = new HashSet(); FactFieldValues = new HashSet(); - InverseDimParentOrcidPublication = new HashSet(); + InverseDimProfileOnlyPublicationNavigation = new HashSet(); } public int Id { get; set; } - public int? DimParentOrcidPublicationId { get; set; } - public int ParentPublicationTypeCode { get; set; } - public int PublicationTypeCode { get; set; } - public int PublicationTypeCode2 { get; set; } + public int? DimProfileOnlyPublicationId { get; set; } + public int ParentTypeClassificationCode { get; set; } + /// + /// code_schema = 'julkaisutyyppiluokitus' + /// + public int TypeClassificationCode { get; set; } + /// + /// code_scheme = 'julkaisumuoto' + /// + public int PublicationFormatCode { get; set; } + /// + /// code_scheme = 'Artikkelintyyppikoodi' + /// public int ArticleTypeCode { get; set; } + /// + /// code_scheme = 'julkaisunyleiso' + /// public int TargetAudienceCode { get; set; } public string OrcidWorkType { get; set; } public string PublicationName { get; set; } @@ -37,7 +49,6 @@ public DimOrcidPublication() public string ParentPublicationName { get; set; } public string ParentPublicationEditors { get; set; } public int? LicenseCode { get; set; } - public string LanguageCode { get; set; } public string OpenAccessCode { get; set; } public string OriginalPublicationId { get; set; } public bool? PeerReviewed { get; set; } @@ -48,19 +59,21 @@ public DimOrcidPublication() public string SourceDescription { get; set; } public DateTime? Created { get; set; } public DateTime? Modified { get; set; } - public int OrcidPersonDataSource { get; set; } + public int DimKnownPersonId { get; set; } public int DimRegisteredDataSourceId { get; set; } + public int LanguageCode { get; set; } public virtual DimReferencedatum ArticleTypeCodeNavigation { get; set; } - public virtual DimOrcidPublication DimParentOrcidPublication { get; set; } + public virtual DimKnownPerson DimKnownPerson { get; set; } + public virtual DimProfileOnlyPublication DimProfileOnlyPublicationNavigation { get; set; } public virtual DimRegisteredDataSource DimRegisteredDataSource { get; set; } - public virtual DimKnownPerson OrcidPersonDataSourceNavigation { get; set; } - public virtual DimReferencedatum ParentPublicationTypeCodeNavigation { get; set; } - public virtual DimReferencedatum PublicationTypeCode2Navigation { get; set; } - public virtual DimReferencedatum PublicationTypeCodeNavigation { get; set; } + public virtual DimReferencedatum LanguageCodeNavigation { get; set; } + public virtual DimReferencedatum ParentTypeClassificationCodeNavigation { get; set; } + public virtual DimReferencedatum PublicationFormatCodeNavigation { get; set; } public virtual DimReferencedatum TargetAudienceCodeNavigation { get; set; } + public virtual DimReferencedatum TypeClassificationCodeNavigation { get; set; } public virtual ICollection DimPids { get; set; } public virtual ICollection FactFieldValues { get; set; } - public virtual ICollection InverseDimParentOrcidPublication { get; set; } + public virtual ICollection InverseDimProfileOnlyPublicationNavigation { get; set; } } } diff --git a/aspnetcore/src/api/Models/Ttv/DimProfileOnlyResearchActivity.cs b/aspnetcore/src/api/Models/Ttv/DimProfileOnlyResearchActivity.cs new file mode 100644 index 00000000..3390228a --- /dev/null +++ b/aspnetcore/src/api/Models/Ttv/DimProfileOnlyResearchActivity.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace api.Models.Ttv +{ + public partial class DimProfileOnlyResearchActivity + { + public DimProfileOnlyResearchActivity() + { + FactFieldValues = new HashSet(); + } + + public int Id { get; set; } + public int DimDateIdStart { get; set; } + public int DimDateIdEnd { get; set; } + public int? DimGeoIdCountry { get; set; } + public int DimOrganizationId { get; set; } + public int DimEventId { get; set; } + public string LocalIdentifier { get; set; } + public string OrcidWorkType { get; set; } + public string NameFi { get; set; } + public string NameSv { get; set; } + public string NameEn { get; set; } + public string NameUnd { get; set; } + public string DescriptionFi { get; set; } + public string DescriptionEn { get; set; } + public string DescriptionSv { get; set; } + public string IndentifierlessTargetOrg { get; set; } + public string SourceId { get; set; } + public string SourceDescription { get; set; } + public DateTime? Created { get; set; } + public DateTime? Modified { get; set; } + public int DimRegisteredDataSourceId { get; set; } + + public virtual DimDate DimDateIdEndNavigation { get; set; } + public virtual DimDate DimDateIdStartNavigation { get; set; } + public virtual DimEvent DimEvent { get; set; } + public virtual DimGeo DimGeoIdCountryNavigation { get; set; } + public virtual DimOrganization DimOrganization { get; set; } + public virtual DimRegisteredDataSource DimRegisteredDataSource { get; set; } + public virtual ICollection FactFieldValues { get; set; } + } +} diff --git a/aspnetcore/src/api/Models/Ttv/DimReferencedatum.cs b/aspnetcore/src/api/Models/Ttv/DimReferencedatum.cs index 13c9db86..02da2e57 100644 --- a/aspnetcore/src/api/Models/Ttv/DimReferencedatum.cs +++ b/aspnetcore/src/api/Models/Ttv/DimReferencedatum.cs @@ -11,11 +11,12 @@ public DimReferencedatum() DimAffiliationAffiliationTypeNavigations = new HashSet(); DimAffiliationPositionCodeNavigations = new HashSet(); DimEducations = new HashSet(); - DimOrcidPublicationArticleTypeCodeNavigations = new HashSet(); - DimOrcidPublicationParentPublicationTypeCodeNavigations = new HashSet(); - DimOrcidPublicationPublicationTypeCode2Navigations = new HashSet(); - DimOrcidPublicationPublicationTypeCodeNavigations = new HashSet(); - DimOrcidPublicationTargetAudienceCodeNavigations = new HashSet(); + DimProfileOnlyPublicationArticleTypeCodeNavigations = new HashSet(); + DimProfileOnlyPublicationLanguageCodeNavigations = new HashSet(); + DimProfileOnlyPublicationParentTypeClassificationCodeNavigations = new HashSet(); + DimProfileOnlyPublicationPublicationFormatCodeNavigations = new HashSet(); + DimProfileOnlyPublicationTargetAudienceCodeNavigations = new HashSet(); + DimProfileOnlyPublicationTypeClassificationCodeNavigations = new HashSet(); DimPublicationArticleTypeCodeNavigations = new HashSet(); DimPublicationParentPublicationTypeCodeNavigations = new HashSet(); DimPublicationPublicationTypeCode2Navigations = new HashSet(); @@ -25,7 +26,8 @@ public DimReferencedatum() DimUserChoices = new HashSet(); FactContributions = new HashSet(); FactDimReferencedataFieldOfSciences = new HashSet(); - FactFieldValues = new HashSet(); + FactFieldValueDimReferencedataActorRoles = new HashSet(); + FactFieldValueDimReferencedataFieldOfSciences = new HashSet(); FactJufoClassCodesForPubChannels = new HashSet(); InverseDimReferencedata = new HashSet(); DimCallProgrammes = new HashSet(); @@ -51,11 +53,12 @@ public DimReferencedatum() public virtual ICollection DimAffiliationAffiliationTypeNavigations { get; set; } public virtual ICollection DimAffiliationPositionCodeNavigations { get; set; } public virtual ICollection DimEducations { get; set; } - public virtual ICollection DimOrcidPublicationArticleTypeCodeNavigations { get; set; } - public virtual ICollection DimOrcidPublicationParentPublicationTypeCodeNavigations { get; set; } - public virtual ICollection DimOrcidPublicationPublicationTypeCode2Navigations { get; set; } - public virtual ICollection DimOrcidPublicationPublicationTypeCodeNavigations { get; set; } - public virtual ICollection DimOrcidPublicationTargetAudienceCodeNavigations { get; set; } + public virtual ICollection DimProfileOnlyPublicationArticleTypeCodeNavigations { get; set; } + public virtual ICollection DimProfileOnlyPublicationLanguageCodeNavigations { get; set; } + public virtual ICollection DimProfileOnlyPublicationParentTypeClassificationCodeNavigations { get; set; } + public virtual ICollection DimProfileOnlyPublicationPublicationFormatCodeNavigations { get; set; } + public virtual ICollection DimProfileOnlyPublicationTargetAudienceCodeNavigations { get; set; } + public virtual ICollection DimProfileOnlyPublicationTypeClassificationCodeNavigations { get; set; } public virtual ICollection DimPublicationArticleTypeCodeNavigations { get; set; } public virtual ICollection DimPublicationParentPublicationTypeCodeNavigations { get; set; } public virtual ICollection DimPublicationPublicationTypeCode2Navigations { get; set; } @@ -65,7 +68,8 @@ public DimReferencedatum() public virtual ICollection DimUserChoices { get; set; } public virtual ICollection FactContributions { get; set; } public virtual ICollection FactDimReferencedataFieldOfSciences { get; set; } - public virtual ICollection FactFieldValues { get; set; } + public virtual ICollection FactFieldValueDimReferencedataActorRoles { get; set; } + public virtual ICollection FactFieldValueDimReferencedataFieldOfSciences { get; set; } public virtual ICollection FactJufoClassCodesForPubChannels { get; set; } public virtual ICollection InverseDimReferencedata { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/DimRegisteredDataSource.cs b/aspnetcore/src/api/Models/Ttv/DimRegisteredDataSource.cs index db7027c2..90f2b25e 100644 --- a/aspnetcore/src/api/Models/Ttv/DimRegisteredDataSource.cs +++ b/aspnetcore/src/api/Models/Ttv/DimRegisteredDataSource.cs @@ -17,8 +17,9 @@ public DimRegisteredDataSource() DimKeywords = new HashSet(); DimKnownPeople = new HashSet(); DimNames = new HashSet(); - DimOrcidPublications = new HashSet(); DimOrganizations = new HashSet(); + DimProfileOnlyPublications = new HashSet(); + DimProfileOnlyResearchActivities = new HashSet(); DimPublications = new HashSet(); DimResearchActivities = new HashSet(); DimResearchCommunities = new HashSet(); @@ -50,8 +51,9 @@ public DimRegisteredDataSource() public virtual ICollection DimKeywords { get; set; } public virtual ICollection DimKnownPeople { get; set; } public virtual ICollection DimNames { get; set; } - public virtual ICollection DimOrcidPublications { get; set; } public virtual ICollection DimOrganizations { get; set; } + public virtual ICollection DimProfileOnlyPublications { get; set; } + public virtual ICollection DimProfileOnlyResearchActivities { get; set; } public virtual ICollection DimPublications { get; set; } public virtual ICollection DimResearchActivities { get; set; } public virtual ICollection DimResearchCommunities { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/FactFieldValue.cs b/aspnetcore/src/api/Models/Ttv/FactFieldValue.cs index e693de15..929b2bb6 100644 --- a/aspnetcore/src/api/Models/Ttv/FactFieldValue.cs +++ b/aspnetcore/src/api/Models/Ttv/FactFieldValue.cs @@ -22,7 +22,7 @@ public partial class FactFieldValue public int DimEmailAddrressId { get; set; } public int DimResearcherDescriptionId { get; set; } public int DimIdentifierlessDataId { get; set; } - public int DimOrcidPublicationId { get; set; } + public int DimProfileOnlyPublicationId { get; set; } public int DimKeywordId { get; set; } public int DimAffiliationId { get; set; } public int DimResearcherToResearchCommunityId { get; set; } @@ -35,6 +35,8 @@ public partial class FactFieldValue public int DimResearchDatasetId { get; set; } public int DimRegisteredDataSourceId { get; set; } public int DimReferencedataFieldOfScienceId { get; set; } + public int DimProfileOnlyResearchActivityId { get; set; } + public int DimReferencedataActorRoleId { get; set; } public virtual DimAffiliation DimAffiliation { get; set; } public virtual DimCompetence DimCompetence { get; set; } @@ -46,10 +48,12 @@ public partial class FactFieldValue public virtual DimIdentifierlessDatum DimIdentifierlessData { get; set; } public virtual DimKeyword DimKeyword { get; set; } public virtual DimName DimName { get; set; } - public virtual DimOrcidPublication DimOrcidPublication { get; set; } public virtual DimPid DimPid { get; set; } public virtual DimPid DimPidIdOrcidPutCodeNavigation { get; set; } + public virtual DimProfileOnlyPublication DimProfileOnlyPublication { get; set; } + public virtual DimProfileOnlyResearchActivity DimProfileOnlyResearchActivity { get; set; } public virtual DimPublication DimPublication { get; set; } + public virtual DimReferencedatum DimReferencedataActorRole { get; set; } public virtual DimReferencedatum DimReferencedataFieldOfScience { get; set; } public virtual DimRegisteredDataSource DimRegisteredDataSource { get; set; } public virtual DimResearchActivity DimResearchActivity { get; set; } diff --git a/aspnetcore/src/api/Models/Ttv/TtvContext.cs b/aspnetcore/src/api/Models/Ttv/TtvContext.cs index 0a31a918..a50686ca 100644 --- a/aspnetcore/src/api/Models/Ttv/TtvContext.cs +++ b/aspnetcore/src/api/Models/Ttv/TtvContext.cs @@ -36,7 +36,6 @@ public TtvContext(DbContextOptions options) public virtual DbSet DimFieldDisplaySettings { get; set; } public virtual DbSet DimFieldOfArts { get; set; } public virtual DbSet DimFieldOfEducations { get; set; } - public virtual DbSet DimFieldOfSciences { get; set; } public virtual DbSet DimFundingDecisions { get; set; } public virtual DbSet DimGeos { get; set; } public virtual DbSet DimIdentifierlessData { get; set; } @@ -49,10 +48,11 @@ public TtvContext(DbContextOptions options) public virtual DbSet DimNames { get; set; } public virtual DbSet DimNewsFeeds { get; set; } public virtual DbSet DimNewsItems { get; set; } - public virtual DbSet DimOrcidPublications { get; set; } public virtual DbSet DimOrganisationMedia { get; set; } public virtual DbSet DimOrganizations { get; set; } public virtual DbSet DimPids { get; set; } + public virtual DbSet DimProfileOnlyPublications { get; set; } + public virtual DbSet DimProfileOnlyResearchActivities { get; set; } public virtual DbSet DimPublications { get; set; } public virtual DbSet DimPublicationChannels { get; set; } public virtual DbSet DimPurposes { get; set; } @@ -80,11 +80,6 @@ public TtvContext(DbContextOptions options) public virtual DbSet FactInfraKeywords { get; set; } public virtual DbSet FactJufoClassCodesForPubChannels { get; set; } public virtual DbSet FactUpkeeps { get; set; } - public virtual DbSet TempBrInfrastructureDimFieldOfSciences { get; set; } - public virtual DbSet TempBrParticipatesInFundingGroups { get; set; } - public virtual DbSet TempDimRegisteredDataSources { get; set; } - public virtual DbSet TempDimRegisteredDataSource20221121s { get; set; } - public virtual DbSet TempFactDimReferencedataFieldOfSciences { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { @@ -99,7 +94,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimResearchDatasetId, e.DimResearchDatasetId2 }) - .HasName("PK__br_datas__9FEA685A5FEE4AEF"); + .HasName("PK__br_datas__9FEA685AADD9C5AE"); entity.ToTable("br_dataset_dataset_relationship"); @@ -128,7 +123,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimFundingDecisionId, e.DimOrganizationid }) - .HasName("PK__br_fundi__3DB567F8F345F076"); + .HasName("PK__br_fundi__3DB567F80481F3E5"); entity.ToTable("br_funding_consortium_participation"); @@ -162,7 +157,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimUserProfileId, e.DimExternalServiceId, e.DimPermittedFieldGroup }) - .HasName("PK__br_grant__F51F7BCB162F9D0B"); + .HasName("PK__br_grant__F51F7BCB09E2D150"); entity.ToTable("br_granted_permissions"); @@ -194,7 +189,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimFundingDecisionid, e.DimNameId }) - .HasName("PK__br_parti__5EC9BC64C923D602"); + .HasName("PK__br_parti__5EC9BC64EFD133AC"); entity.ToTable("br_participates_in_funding_group"); @@ -290,7 +285,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimWordClusterId, e.DimFundingDecisionId }) - .HasName("PK__br_word___7D640B5A0254B61D"); + .HasName("PK__br_word___7D640B5AB5141850"); entity.ToTable("br_word_cluster_dim_funding_decision"); @@ -331,89 +326,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimMinedWordsId, e.DimWordClusterId }) - .HasName("PK__br_words__0602FA372F9B857F"); - - entity.ToTable("br_words_define_a_cluster"); - - entity.Property(e => e.DimMinedWordsId).HasColumnName("dim_mined_words_id"); - - entity.Property(e => e.DimWordClusterId).HasColumnName("dim_word_cluster_id"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - - entity.HasOne(d => d.DimMinedWords) - .WithMany(p => p.BrWordsDefineAClusters) - .HasForeignKey(d => d.DimMinedWordsId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKbr_words_d537149"); - - entity.HasOne(d => d.DimWordCluster) - .WithMany(p => p.BrWordsDefineAClusters) - .HasForeignKey(d => d.DimWordClusterId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKbr_words_d714819"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => new { e.DimWordClusterId, e.DimFundingDecisionId }) - .HasName("PK__br_word___7D640B5A3F85B915"); - - entity.ToTable("br_word_cluster_dim_funding_decision"); - - entity.Property(e => e.DimWordClusterId).HasColumnName("dim_word_cluster_id"); - - entity.Property(e => e.DimFundingDecisionId).HasColumnName("dim_funding_decision_id"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - - entity.HasOne(d => d.DimFundingDecision) - .WithMany(p => p.BrWordClusterDimFundingDecisions) - .HasForeignKey(d => d.DimFundingDecisionId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKbr_word_cl350721"); - - entity.HasOne(d => d.DimWordCluster) - .WithMany(p => p.BrWordClusterDimFundingDecisions) - .HasForeignKey(d => d.DimWordClusterId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKbr_word_cl424955"); - }); - - modelBuilder.Entity(entity => - { - entity.HasKey(e => new { e.DimMinedWordsId, e.DimWordClusterId }) - .HasName("PK__br_words__0602FA370C173B6A"); + .HasName("PK__br_words__0602FA37E3786E84"); entity.ToTable("br_words_define_a_cluster"); @@ -471,6 +384,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.EndDate).HasColumnName("end_date"); + entity.Property(e => e.LocalIdentifier) + .HasMaxLength(255) + .HasColumnName("local_identifier"); + entity.Property(e => e.Modified) .HasColumnType("datetime") .HasColumnName("modified"); @@ -557,6 +474,18 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.ApplicationTermsSv).HasColumnName("application_terms_sv"); + entity.Property(e => e.CallNameDetailsEn) + .HasMaxLength(255) + .HasColumnName("call_name_details_en"); + + entity.Property(e => e.CallNameDetailsFi) + .HasMaxLength(255) + .HasColumnName("call_name_details_fi"); + + entity.Property(e => e.CallNameDetailsSv) + .HasMaxLength(255) + .HasColumnName("call_name_details_sv"); + entity.Property(e => e.ContactInformation).HasColumnName("contact_information"); entity.Property(e => e.ContinuousApplicationPeriod).HasColumnName("continuous_application_period"); @@ -648,7 +577,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimCallProgrammeId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("belongs to / a part of "), j => { - j.HasKey("DimCallProgrammeId", "DimCallProgrammeId2").HasName("PK__br_call___6F0CEDFB5685F50B"); + j.HasKey("DimCallProgrammeId", "DimCallProgrammeId2").HasName("PK__br_call___6F0CEDFB8C104827"); j.ToTable("br_call_programme_dim_call_programme"); @@ -665,7 +594,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimCallProgrammeId2").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_call_pr785575"), j => { - j.HasKey("DimCallProgrammeId", "DimCallProgrammeId2").HasName("PK__br_call___6F0CEDFB5685F50B"); + j.HasKey("DimCallProgrammeId", "DimCallProgrammeId2").HasName("PK__br_call___6F0CEDFB8C104827"); j.ToTable("br_call_programme_dim_call_programme"); @@ -682,7 +611,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimCallProgrammeId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("has disciplines"), j => { - j.HasKey("DimCallProgrammeId", "DimReferencedataId").HasName("PK__br_dim_r__0A5B885D0996EA60"); + j.HasKey("DimCallProgrammeId", "DimReferencedataId").HasName("PK__br_dim_r__0A5B885DCFE639D5"); j.ToTable("br_dim_referencedata_dim_call_programme"); @@ -987,7 +916,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimEsfriId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_esfri_d559740"), j => { - j.HasKey("DimEsfriId", "DimInfrastructureId").HasName("PK__br_esfri__A4A0FE10B16F3C75"); + j.HasKey("DimEsfriId", "DimInfrastructureId").HasName("PK__br_esfri__A4A0FE1022E4351B"); j.ToTable("br_esfri_dim_infrastructure"); @@ -1154,7 +1083,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFieldDisplaySettingsId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_field_d783303"), j => { - j.HasKey("DimFieldDisplaySettingsId", "DimRegisteredDataSourceId").HasName("PK__br_field__6148A77275EFD9AC"); + j.HasKey("DimFieldDisplaySettingsId", "DimRegisteredDataSourceId").HasName("PK__br_field__6148A7721283CB14"); j.ToTable("br_field_display_settings_dim_registered_data_source"); @@ -1213,7 +1142,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFieldOfArtId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_field_o978876"), j => { - j.HasKey("DimFieldOfArtId", "DimPublicationId").HasName("PK__br_field__809A87CDCEDC37CF"); + j.HasKey("DimFieldOfArtId", "DimPublicationId").HasName("PK__br_field__809A87CDB8546B72"); j.ToTable("br_field_of_art_dim_publication"); @@ -1272,7 +1201,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFieldOfEducationId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_field_o983513"), j => { - j.HasKey("DimFieldOfEducationId", "DimPublicationId").HasName("PK__br_field__6E377B2C72EE1ED6"); + j.HasKey("DimFieldOfEducationId", "DimPublicationId").HasName("PK__br_field__6E377B2C14E80815"); j.ToTable("br_field_of_education_dim_publication"); @@ -1282,48 +1211,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) }); }); - modelBuilder.Entity(entity => - { - entity.ToTable("dim_field_of_science"); - - entity.Property(e => e.Id).HasColumnName("id"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.FieldId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("field_id"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.NameEn) - .HasMaxLength(255) - .HasColumnName("name_en"); - - entity.Property(e => e.NameFi) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("name_fi"); - - entity.Property(e => e.NameSv) - .HasMaxLength(255) - .HasColumnName("name_sv"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - }); - modelBuilder.Entity(entity => { entity.ToTable("dim_funding_decision"); @@ -1485,7 +1372,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFundingDecisionId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_funding281737"), j => { - j.HasKey("DimFundingDecisionId", "DimFieldOfArtId").HasName("PK__br_fundi__07CB586D4C093A8E"); + j.HasKey("DimFundingDecisionId", "DimFieldOfArtId").HasName("PK__br_fundi__07CB586D00C6A0D4"); j.ToTable("br_funding_decision_dim_field_of_art"); @@ -1502,7 +1389,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFundingDecisionToId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_previou440746"), j => { - j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_previ__90966491010226C7"); + j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_previ__90966491B50489D9"); j.ToTable("br_previous_funding_decision"); @@ -1519,7 +1406,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFundingDecisionToId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_related689923"), j => { - j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_relat__909664918926D3B7"); + j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_relat__909664919D3CC888"); j.ToTable("br_related_funding_decision"); @@ -1536,7 +1423,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFundingDecisionFromId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_previou481541"), j => { - j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_previ__90966491010226C7"); + j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_previ__90966491B50489D9"); j.ToTable("br_previous_funding_decision"); @@ -1553,7 +1440,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimFundingDecisionFromId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_related232364"), j => { - j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_relat__909664918926D3B7"); + j.HasKey("DimFundingDecisionFromId", "DimFundingDecisionToId").HasName("PK__br_relat__909664919D3CC888"); j.ToTable("br_related_funding_decision"); @@ -1859,7 +1746,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimKeywordId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_keyword224605"), j => { - j.HasKey("DimKeywordId", "DimFundingDecisionId").HasName("PK__br_keywo__8C7B929B63C03C1E"); + j.HasKey("DimKeywordId", "DimFundingDecisionId").HasName("PK__br_keywo__8C7B929B746A6E8E"); j.ToTable("br_keyword_dim_funding_decision"); @@ -1876,7 +1763,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimKeywordId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_keyword944303"), j => { - j.HasKey("DimKeywordId", "DimPublicationId").HasName("PK__br_keywo__C6E31F1A50941DF8"); + j.HasKey("DimKeywordId", "DimPublicationId").HasName("PK__br_keywo__C6E31F1AC6F3589D"); j.ToTable("br_keyword_dim_publication"); @@ -2018,7 +1905,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimMerilId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_meril_d209645"), j => { - j.HasKey("DimMerilId", "DimInfrastructureId").HasName("PK__br_meril__A30C54DAB06A58AC"); + j.HasKey("DimMerilId", "DimInfrastructureId").HasName("PK__br_meril__A30C54DA7D01ADAC"); j.ToTable("br_meril_dim_infrastructure"); @@ -2057,35 +1944,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasColumnName("word"); }); - modelBuilder.Entity(entity => - { - entity.ToTable("dim_mined_words"); - - entity.Property(e => e.Id).HasColumnName("id"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - - entity.Property(e => e.Word) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("word"); - }); - modelBuilder.Entity(entity => { entity.ToTable("dim_name"); @@ -2177,7 +2035,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.Id, e.DimNewsFeedid }) - .HasName("PK__dim_news__B87E6703459D631B"); + .HasName("PK__dim_news__B87E6703D2C2ACE8"); entity.ToTable("dim_news_item"); @@ -2223,280 +2081,105 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasConstraintName("FKdim_news_i691810"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { - entity.ToTable("dim_orcid_publication"); + entity.HasNoKey(); - entity.Property(e => e.Id).HasColumnName("id"); + entity.ToTable("dim_organisation_media"); - entity.Property(e => e.ArticleNumberText) + entity.Property(e => e.Created) + .HasColumnType("datetime") + .HasColumnName("created"); + + entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); + + entity.Property(e => e.LanguageVariant) .HasMaxLength(255) - .HasColumnName("article_number_text"); + .HasColumnName("language_variant"); - entity.Property(e => e.ArticleTypeCode).HasColumnName("article_type_code"); + entity.Property(e => e.MediaUri) + .HasMaxLength(511) + .HasColumnName("media_uri"); - entity.Property(e => e.AuthorsText) + entity.Property(e => e.Modified) + .HasColumnType("datetime") + .HasColumnName("modified"); + + entity.Property(e => e.SourceDescription) + .HasMaxLength(255) + .HasColumnName("source_description"); + + entity.Property(e => e.SourceId) .IsRequired() - .HasColumnName("authors_text"); + .HasMaxLength(255) + .HasColumnName("source_id"); - entity.Property(e => e.ConferenceName) - .HasMaxLength(4000) - .HasColumnName("conference_name"); + entity.HasOne(d => d.DimOrganization) + .WithMany() + .HasForeignKey(d => d.DimOrganizationId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKdim_organi623202"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("dim_organization"); + + entity.Property(e => e.Id).HasColumnName("id"); + + entity.Property(e => e.CountryCode) + .HasMaxLength(2) + .HasColumnName("country_code"); entity.Property(e => e.Created) .HasColumnType("datetime") .HasColumnName("created"); - entity.Property(e => e.DimParentOrcidPublicationId).HasColumnName("dim_parent_orcid_publication id"); + entity.Property(e => e.DegreeCountBsc).HasColumnName("degree_count_bsc"); + + entity.Property(e => e.DegreeCountLic).HasColumnName("degree_count_lic"); + + entity.Property(e => e.DegreeCountMsc).HasColumnName("degree_count_msc"); + + entity.Property(e => e.DegreeCountPhd).HasColumnName("degree_count_phd"); + + entity.Property(e => e.DimOrganizationBroader).HasColumnName("dim_organization_broader"); entity.Property(e => e.DimRegisteredDataSourceId).HasColumnName("dim_registered_data_source_id"); - entity.Property(e => e.DoiHandle) - .HasMaxLength(4000) - .HasColumnName("doi_handle"); + entity.Property(e => e.DimSectorid).HasColumnName("dim_sectorid"); - entity.Property(e => e.IssueNumber) - .HasMaxLength(255) - .HasColumnName("issue_number"); + entity.Property(e => e.Established) + .HasColumnType("datetime") + .HasColumnName("established"); - entity.Property(e => e.LanguageCode) + entity.Property(e => e.LocalOrganizationSector) .HasMaxLength(255) - .HasColumnName("language_code"); + .HasColumnName("local_organization_sector"); - entity.Property(e => e.LicenseCode).HasColumnName("license_code"); + entity.Property(e => e.LocalOrganizationUnitId) + .HasMaxLength(255) + .HasColumnName("local_organization_unit_Id"); entity.Property(e => e.Modified) .HasColumnType("datetime") .HasColumnName("modified"); - entity.Property(e => e.NumberOfAuthors).HasColumnName("number_of_authors"); - - entity.Property(e => e.OpenAccessCode) + entity.Property(e => e.NameEn) .HasMaxLength(255) - .HasColumnName("open_access_code"); - - entity.Property(e => e.OrcidPersonDataSource).HasColumnName("orcid_person_data_source"); + .HasColumnName("name_en"); - entity.Property(e => e.OrcidWorkType) + entity.Property(e => e.NameFi) .HasMaxLength(255) - .HasColumnName("orcid_work_type"); + .HasColumnName("name_fi"); - entity.Property(e => e.OriginalPublicationId) + entity.Property(e => e.NameSv) .HasMaxLength(255) - .HasColumnName("original_publication_id"); + .HasColumnName("name_sv"); - entity.Property(e => e.PageNumberText) + entity.Property(e => e.NameUnd) .HasMaxLength(255) - .HasColumnName("page_number_text"); - - entity.Property(e => e.ParentPublicationEditors) - .HasMaxLength(4000) - .HasColumnName("parent_publication_editors"); - - entity.Property(e => e.ParentPublicationName) - .HasMaxLength(4000) - .HasColumnName("parent_publication_name"); - - entity.Property(e => e.ParentPublicationTypeCode).HasColumnName("parent_publication_type_code"); - - entity.Property(e => e.PeerReviewed).HasColumnName("peer_reviewed"); - - entity.Property(e => e.PublicationCountryCode) - .HasMaxLength(255) - .HasColumnName("publication_country_code"); - - entity.Property(e => e.PublicationId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("publication_id"); - - entity.Property(e => e.PublicationName) - .IsRequired() - .HasMaxLength(4000) - .HasColumnName("publication_name"); - - entity.Property(e => e.PublicationTypeCode).HasColumnName("publication_type_code"); - - entity.Property(e => e.PublicationTypeCode2).HasColumnName("publication_type_code2"); - - entity.Property(e => e.PublicationYear).HasColumnName("publication_year"); - - entity.Property(e => e.PublisherLocation) - .HasMaxLength(255) - .HasColumnName("publisher_location"); - - entity.Property(e => e.PublisherName) - .HasMaxLength(4000) - .HasColumnName("publisher_name"); - - entity.Property(e => e.Report).HasColumnName("report"); - - entity.Property(e => e.ShortDescription).HasColumnName("short_description"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - - entity.Property(e => e.TargetAudienceCode).HasColumnName("target_audience_code"); - - entity.Property(e => e.ThesisTypeCode).HasColumnName("thesis_type_code"); - - entity.Property(e => e.Volume) - .HasMaxLength(255) - .HasColumnName("volume"); - - entity.HasOne(d => d.ArticleTypeCodeNavigation) - .WithMany(p => p.DimOrcidPublicationArticleTypeCodeNavigations) - .HasForeignKey(d => d.ArticleTypeCode) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("Or_article_type_code"); - - entity.HasOne(d => d.DimParentOrcidPublication) - .WithMany(p => p.InverseDimParentOrcidPublication) - .HasForeignKey(d => d.DimParentOrcidPublicationId) - .HasConstraintName("parent orcid publication"); - - entity.HasOne(d => d.DimRegisteredDataSource) - .WithMany(p => p.DimOrcidPublications) - .HasForeignKey(d => d.DimRegisteredDataSourceId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKdim_orcid_729203"); - - entity.HasOne(d => d.OrcidPersonDataSourceNavigation) - .WithMany(p => p.DimOrcidPublications) - .HasForeignKey(d => d.OrcidPersonDataSource) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKdim_orcid_438595"); - - entity.HasOne(d => d.ParentPublicationTypeCodeNavigation) - .WithMany(p => p.DimOrcidPublicationParentPublicationTypeCodeNavigations) - .HasForeignKey(d => d.ParentPublicationTypeCode) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("Or_parent_publication_type_code"); - - entity.HasOne(d => d.PublicationTypeCodeNavigation) - .WithMany(p => p.DimOrcidPublicationPublicationTypeCodeNavigations) - .HasForeignKey(d => d.PublicationTypeCode) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("publication_type_code"); - - entity.HasOne(d => d.PublicationTypeCode2Navigation) - .WithMany(p => p.DimOrcidPublicationPublicationTypeCode2Navigations) - .HasForeignKey(d => d.PublicationTypeCode2) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("Or_publication_type_code2"); - - entity.HasOne(d => d.TargetAudienceCodeNavigation) - .WithMany(p => p.DimOrcidPublicationTargetAudienceCodeNavigations) - .HasForeignKey(d => d.TargetAudienceCode) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("Or_target_audience_code"); - }); - - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("dim_organisation_media"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); - - entity.Property(e => e.LanguageVariant) - .HasMaxLength(255) - .HasColumnName("language_variant"); - - entity.Property(e => e.MediaUri) - .HasMaxLength(511) - .HasColumnName("media_uri"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - - entity.HasOne(d => d.DimOrganization) - .WithMany() - .HasForeignKey(d => d.DimOrganizationId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKdim_organi623202"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("dim_organization"); - - entity.Property(e => e.Id).HasColumnName("id"); - - entity.Property(e => e.CountryCode) - .HasMaxLength(2) - .HasColumnName("country_code"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.DegreeCountBsc).HasColumnName("degree_count_bsc"); - - entity.Property(e => e.DegreeCountLic).HasColumnName("degree_count_lic"); - - entity.Property(e => e.DegreeCountMsc).HasColumnName("degree_count_msc"); - - entity.Property(e => e.DegreeCountPhd).HasColumnName("degree_count_phd"); - - entity.Property(e => e.DimOrganizationBroader).HasColumnName("dim_organization_broader"); - - entity.Property(e => e.DimRegisteredDataSourceId).HasColumnName("dim_registered_data_source_id"); - - entity.Property(e => e.DimSectorid).HasColumnName("dim_sectorid"); - - entity.Property(e => e.Established) - .HasColumnType("datetime") - .HasColumnName("established"); - - entity.Property(e => e.LocalOrganizationSector) - .HasMaxLength(255) - .HasColumnName("local_organization_sector"); - - entity.Property(e => e.LocalOrganizationUnitId) - .HasMaxLength(255) - .HasColumnName("local_organization_unit_Id"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.NameEn) - .HasMaxLength(255) - .HasColumnName("name_en"); - - entity.Property(e => e.NameFi) - .HasMaxLength(255) - .HasColumnName("name_fi"); - - entity.Property(e => e.NameSv) - .HasMaxLength(255) - .HasColumnName("name_sv"); - - entity.Property(e => e.NameUnd) - .HasMaxLength(255) - .HasColumnName("name_und"); + .HasColumnName("name_und"); entity.Property(e => e.NameVariants) .HasMaxLength(1023) @@ -2560,7 +2243,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimOrganizationid").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_organiz621686"), j => { - j.HasKey("DimOrganizationid", "DimCallProgrammeid").HasName("PK__br_organ__10F219BC602A8F57"); + j.HasKey("DimOrganizationid", "DimCallProgrammeid").HasName("PK__br_organ__10F219BC8E0FA610"); j.ToTable("br_organizations_fund_call_programmes"); @@ -2577,7 +2260,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimOrganizationid").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_predece849307"), j => { - j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_prede__A7CAD2F4E27E76D6"); + j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_prede__A7CAD2F4634729A3"); j.ToTable("br_predecessor_organization"); @@ -2594,7 +2277,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimOrganizationid").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_success452227"), j => { - j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_succe__A7CAD2F4C892F51F"); + j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_succe__A7CAD2F46839BB93"); j.ToTable("br_successor organization"); @@ -2611,7 +2294,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimOrganizationid2").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_predece505451"), j => { - j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_prede__A7CAD2F4E27E76D6"); + j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_prede__A7CAD2F4634729A3"); j.ToTable("br_predecessor_organization"); @@ -2628,7 +2311,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimOrganizationid2").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_success902531"), j => { - j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_succe__A7CAD2F4C892F51F"); + j.HasKey("DimOrganizationid", "DimOrganizationid2").HasName("PK__br_succe__A7CAD2F46839BB93"); j.ToTable("br_successor organization"); @@ -2638,9 +2321,326 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) }); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => + { + entity.ToTable("dim_pid"); + + entity.Property(e => e.Id).HasColumnName("id"); + + entity.Property(e => e.Created) + .HasColumnType("datetime") + .HasColumnName("created"); + + entity.Property(e => e.DimEventId).HasColumnName("dim_event_id"); + + entity.Property(e => e.DimFundingDecisionId).HasColumnName("dim_funding_decision_id"); + + entity.Property(e => e.DimInfrastructureId).HasColumnName("dim_infrastructure_id"); + + entity.Property(e => e.DimKnownPersonId).HasColumnName("dim_known_person_id"); + + entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); + + entity.Property(e => e.DimProfileOnlyPublicationId).HasColumnName("dim_profile_only_publication_id"); + + entity.Property(e => e.DimPublicationChannelId).HasColumnName("dim_publication_channel_id"); + + entity.Property(e => e.DimPublicationId).HasColumnName("dim_publication_id"); + + entity.Property(e => e.DimResearchActivityId).HasColumnName("dim_research_activity_id"); + + entity.Property(e => e.DimResearchDataCatalogId).HasColumnName("dim_research_data_catalog_id"); + + entity.Property(e => e.DimResearchDatasetId).HasColumnName("dim_research_dataset_id"); + + entity.Property(e => e.DimServiceId).HasColumnName("dim_service_id"); + + entity.Property(e => e.Modified) + .HasColumnType("datetime") + .HasColumnName("modified"); + + entity.Property(e => e.PidContent) + .IsRequired() + .HasMaxLength(255) + .HasColumnName("pid_content"); + + entity.Property(e => e.PidType) + .IsRequired() + .HasMaxLength(255) + .HasColumnName("pid_type"); + + entity.Property(e => e.SourceDescription) + .HasMaxLength(255) + .HasColumnName("source_description"); + + entity.Property(e => e.SourceId) + .IsRequired() + .HasMaxLength(255) + .HasColumnName("source_id"); + + entity.HasOne(d => d.DimEvent) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimEventId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("event_identifier"); + + entity.HasOne(d => d.DimFundingDecision) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimFundingDecisionId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("ROI/RAID"); + + entity.HasOne(d => d.DimInfrastructure) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimInfrastructureId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("URN/infrastructure"); + + entity.HasOne(d => d.DimKnownPerson) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimKnownPersonId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Orcid/ISNI"); + + entity.HasOne(d => d.DimOrganization) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimOrganizationId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("ISNI/GRID/ROR/Business-ID\\PIC"); + + entity.HasOne(d => d.DimProfileOnlyPublication) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimProfileOnlyPublicationId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("ll"); + + entity.HasOne(d => d.DimPublicationChannel) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimPublicationChannelId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("mostly ISSN"); + + entity.HasOne(d => d.DimPublication) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimPublicationId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("DOI/ISBN1-2"); + + entity.HasOne(d => d.DimResearchActivity) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimResearchActivityId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKdim_pid725718"); + + entity.HasOne(d => d.DimResearchDataCatalog) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimResearchDataCatalogId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKdim_pid400266"); + + entity.HasOne(d => d.DimResearchDataset) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimResearchDatasetId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("URN/DOI"); + + entity.HasOne(d => d.DimService) + .WithMany(p => p.DimPids) + .HasForeignKey(d => d.DimServiceId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("URN/service"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("dim_profile_only_publication"); + + entity.Property(e => e.Id).HasColumnName("id"); + + entity.Property(e => e.ArticleNumberText) + .HasMaxLength(255) + .HasColumnName("article_number_text"); + + entity.Property(e => e.ArticleTypeCode) + .HasColumnName("article_type_code") + .HasComment("code_scheme = 'Artikkelintyyppikoodi'"); + + entity.Property(e => e.AuthorsText) + .IsRequired() + .HasColumnName("authors_text"); + + entity.Property(e => e.ConferenceName) + .HasMaxLength(4000) + .HasColumnName("conference_name"); + + entity.Property(e => e.Created) + .HasColumnType("datetime") + .HasColumnName("created"); + + entity.Property(e => e.DimKnownPersonId).HasColumnName("dim_known_person_id"); + + entity.Property(e => e.DimProfileOnlyPublicationId).HasColumnName("dim_profile_only_publication_id"); + + entity.Property(e => e.DimRegisteredDataSourceId).HasColumnName("dim_registered_data_source_id"); + + entity.Property(e => e.DoiHandle) + .HasMaxLength(4000) + .HasColumnName("doi_handle"); + + entity.Property(e => e.IssueNumber) + .HasMaxLength(255) + .HasColumnName("issue_number"); + + entity.Property(e => e.LanguageCode).HasColumnName("language_code"); + + entity.Property(e => e.LicenseCode).HasColumnName("license_code"); + + entity.Property(e => e.Modified) + .HasColumnType("datetime") + .HasColumnName("modified"); + + entity.Property(e => e.NumberOfAuthors).HasColumnName("number_of_authors"); + + entity.Property(e => e.OpenAccessCode) + .HasMaxLength(255) + .HasColumnName("open_access_code"); + + entity.Property(e => e.OrcidWorkType) + .HasMaxLength(255) + .HasColumnName("orcid_work_type"); + + entity.Property(e => e.OriginalPublicationId) + .HasMaxLength(255) + .HasColumnName("original_publication_id"); + + entity.Property(e => e.PageNumberText) + .HasMaxLength(255) + .HasColumnName("page_number_text"); + + entity.Property(e => e.ParentPublicationEditors) + .HasMaxLength(4000) + .HasColumnName("parent_publication_editors"); + + entity.Property(e => e.ParentPublicationName) + .HasMaxLength(4000) + .HasColumnName("parent_publication_name"); + + entity.Property(e => e.ParentTypeClassificationCode).HasColumnName("parent_type_classification_code"); + + entity.Property(e => e.PeerReviewed).HasColumnName("peer_reviewed"); + + entity.Property(e => e.PublicationCountryCode) + .HasMaxLength(255) + .HasColumnName("publication_country_code"); + + entity.Property(e => e.PublicationFormatCode) + .HasColumnName("publication_format_code") + .HasComment("code_scheme = 'julkaisumuoto'"); + + entity.Property(e => e.PublicationId) + .IsRequired() + .HasMaxLength(255) + .HasColumnName("publication_id"); + + entity.Property(e => e.PublicationName) + .IsRequired() + .HasMaxLength(4000) + .HasColumnName("publication_name"); + + entity.Property(e => e.PublicationYear).HasColumnName("publication_year"); + + entity.Property(e => e.PublisherLocation) + .HasMaxLength(255) + .HasColumnName("publisher_location"); + + entity.Property(e => e.PublisherName) + .HasMaxLength(4000) + .HasColumnName("publisher_name"); + + entity.Property(e => e.Report).HasColumnName("report"); + + entity.Property(e => e.ShortDescription).HasColumnName("short_description"); + + entity.Property(e => e.SourceDescription) + .HasMaxLength(255) + .HasColumnName("source_description"); + + entity.Property(e => e.SourceId) + .IsRequired() + .HasMaxLength(255) + .HasColumnName("source_id"); + + entity.Property(e => e.TargetAudienceCode) + .HasColumnName("target_audience_code") + .HasComment("code_scheme = 'julkaisunyleiso'"); + + entity.Property(e => e.ThesisTypeCode).HasColumnName("thesis_type_code"); + + entity.Property(e => e.TypeClassificationCode) + .HasColumnName("type_classification_code") + .HasComment("code_schema = 'julkaisutyyppiluokitus'"); + + entity.Property(e => e.Volume) + .HasMaxLength(255) + .HasColumnName("volume"); + + entity.HasOne(d => d.ArticleTypeCodeNavigation) + .WithMany(p => p.DimProfileOnlyPublicationArticleTypeCodeNavigations) + .HasForeignKey(d => d.ArticleTypeCode) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Or_article_type_code"); + + entity.HasOne(d => d.DimKnownPerson) + .WithMany(p => p.DimProfileOnlyPublications) + .HasForeignKey(d => d.DimKnownPersonId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKdim_orcid_438595"); + + entity.HasOne(d => d.DimProfileOnlyPublicationNavigation) + .WithMany(p => p.InverseDimProfileOnlyPublicationNavigation) + .HasForeignKey(d => d.DimProfileOnlyPublicationId) + .HasConstraintName("parent orcid publication"); + + entity.HasOne(d => d.DimRegisteredDataSource) + .WithMany(p => p.DimProfileOnlyPublications) + .HasForeignKey(d => d.DimRegisteredDataSourceId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKdim_orcid_729203"); + + entity.HasOne(d => d.LanguageCodeNavigation) + .WithMany(p => p.DimProfileOnlyPublicationLanguageCodeNavigations) + .HasForeignKey(d => d.LanguageCode) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("language_code"); + + entity.HasOne(d => d.ParentTypeClassificationCodeNavigation) + .WithMany(p => p.DimProfileOnlyPublicationParentTypeClassificationCodeNavigations) + .HasForeignKey(d => d.ParentTypeClassificationCode) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Or_parent_publication_type_code"); + + entity.HasOne(d => d.PublicationFormatCodeNavigation) + .WithMany(p => p.DimProfileOnlyPublicationPublicationFormatCodeNavigations) + .HasForeignKey(d => d.PublicationFormatCode) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Or_publication_type_code2"); + + entity.HasOne(d => d.TargetAudienceCodeNavigation) + .WithMany(p => p.DimProfileOnlyPublicationTargetAudienceCodeNavigations) + .HasForeignKey(d => d.TargetAudienceCode) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Or_target_audience_code"); + + entity.HasOne(d => d.TypeClassificationCodeNavigation) + .WithMany(p => p.DimProfileOnlyPublicationTypeClassificationCodeNavigations) + .HasForeignKey(d => d.TypeClassificationCode) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("publication_type_code"); + }); + + modelBuilder.Entity(entity => { - entity.ToTable("dim_pid"); + entity.ToTable("dim_profile_only_research_activity"); entity.Property(e => e.Id).HasColumnName("id"); @@ -2648,43 +2648,55 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasColumnType("datetime") .HasColumnName("created"); - entity.Property(e => e.DimEventId).HasColumnName("dim_event_id"); - - entity.Property(e => e.DimFundingDecisionId).HasColumnName("dim_funding_decision_id"); + entity.Property(e => e.DescriptionEn).HasColumnName("description_en"); - entity.Property(e => e.DimInfrastructureId).HasColumnName("dim_infrastructure_id"); + entity.Property(e => e.DescriptionFi).HasColumnName("description_fi"); - entity.Property(e => e.DimKnownPersonId).HasColumnName("dim_known_person_id"); + entity.Property(e => e.DescriptionSv).HasColumnName("description_sv"); - entity.Property(e => e.DimOrcidPublicationId).HasColumnName("dim_orcid_publication_id"); + entity.Property(e => e.DimDateIdEnd).HasColumnName("dim_date_id_end"); - entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); + entity.Property(e => e.DimDateIdStart).HasColumnName("dim_date_id_start"); - entity.Property(e => e.DimPublicationChannelId).HasColumnName("dim_publication_channel_id"); + entity.Property(e => e.DimEventId).HasColumnName("dim_event_id"); - entity.Property(e => e.DimPublicationId).HasColumnName("dim_publication_id"); + entity.Property(e => e.DimGeoIdCountry).HasColumnName("dim_geo_id_country"); - entity.Property(e => e.DimResearchActivityId).HasColumnName("dim_research_activity_id"); + entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); - entity.Property(e => e.DimResearchDataCatalogId).HasColumnName("dim_research_data_catalog_id"); + entity.Property(e => e.DimRegisteredDataSourceId).HasColumnName("dim_registered_data_source_id"); - entity.Property(e => e.DimResearchDatasetId).HasColumnName("dim_research_dataset_id"); + entity.Property(e => e.IndentifierlessTargetOrg) + .HasMaxLength(511) + .HasColumnName("indentifierless_target_org"); - entity.Property(e => e.DimServiceId).HasColumnName("dim_service_id"); + entity.Property(e => e.LocalIdentifier) + .HasMaxLength(255) + .HasColumnName("local_identifier"); entity.Property(e => e.Modified) .HasColumnType("datetime") .HasColumnName("modified"); - entity.Property(e => e.PidContent) - .IsRequired() + entity.Property(e => e.NameEn) .HasMaxLength(255) - .HasColumnName("pid_content"); + .HasColumnName("name_en"); - entity.Property(e => e.PidType) - .IsRequired() + entity.Property(e => e.NameFi) .HasMaxLength(255) - .HasColumnName("pid_type"); + .HasColumnName("name_fi"); + + entity.Property(e => e.NameSv) + .HasMaxLength(255) + .HasColumnName("name_sv"); + + entity.Property(e => e.NameUnd) + .HasMaxLength(255) + .HasColumnName("name_und"); + + entity.Property(e => e.OrcidWorkType) + .HasMaxLength(255) + .HasColumnName("orcid_work_type"); entity.Property(e => e.SourceDescription) .HasMaxLength(255) @@ -2695,77 +2707,40 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasMaxLength(255) .HasColumnName("source_id"); - entity.HasOne(d => d.DimEvent) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimEventId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("event_identifier"); - - entity.HasOne(d => d.DimFundingDecision) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimFundingDecisionId) + entity.HasOne(d => d.DimDateIdEndNavigation) + .WithMany(p => p.DimProfileOnlyResearchActivityDimDateIdEndNavigations) + .HasForeignKey(d => d.DimDateIdEnd) .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("ROI/RAID"); + .HasConstraintName("FKdim_profil457771"); - entity.HasOne(d => d.DimInfrastructure) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimInfrastructureId) + entity.HasOne(d => d.DimDateIdStartNavigation) + .WithMany(p => p.DimProfileOnlyResearchActivityDimDateIdStartNavigations) + .HasForeignKey(d => d.DimDateIdStart) .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("URN/infrastructure"); + .HasConstraintName("FKdim_profil158500"); - entity.HasOne(d => d.DimKnownPerson) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimKnownPersonId) + entity.HasOne(d => d.DimEvent) + .WithMany(p => p.DimProfileOnlyResearchActivities) + .HasForeignKey(d => d.DimEventId) .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("Orcid/ISNI"); + .HasConstraintName("FKdim_profil693884"); - entity.HasOne(d => d.DimOrcidPublication) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimOrcidPublicationId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("ll"); + entity.HasOne(d => d.DimGeoIdCountryNavigation) + .WithMany(p => p.DimProfileOnlyResearchActivities) + .HasForeignKey(d => d.DimGeoIdCountry) + .HasConstraintName("FKdim_profil903211"); entity.HasOne(d => d.DimOrganization) - .WithMany(p => p.DimPids) + .WithMany(p => p.DimProfileOnlyResearchActivities) .HasForeignKey(d => d.DimOrganizationId) .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("ISNI/GRID/ROR/Business-ID\\PIC"); - - entity.HasOne(d => d.DimPublicationChannel) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimPublicationChannelId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("mostly ISSN"); - - entity.HasOne(d => d.DimPublication) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimPublicationId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("DOI/ISBN1-2"); - - entity.HasOne(d => d.DimResearchActivity) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimResearchActivityId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKdim_pid725718"); - - entity.HasOne(d => d.DimResearchDataCatalog) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimResearchDataCatalogId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKdim_pid400266"); - - entity.HasOne(d => d.DimResearchDataset) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimResearchDatasetId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("URN/DOI"); + .HasConstraintName("FKdim_profil273177"); - entity.HasOne(d => d.DimService) - .WithMany(p => p.DimPids) - .HasForeignKey(d => d.DimServiceId) + entity.HasOne(d => d.DimRegisteredDataSource) + .WithMany(p => p.DimProfileOnlyResearchActivities) + .HasForeignKey(d => d.DimRegisteredDataSourceId) .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("URN/service"); + .HasConstraintName("FKdim_profil285579"); }); modelBuilder.Entity(entity => @@ -3003,7 +2978,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimPublicationId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_artpubl464312"), j => { - j.HasKey("DimPublicationId", "DimReferencedataid").HasName("PK__br_artpu__879F18F30B75E11C"); + j.HasKey("DimPublicationId", "DimReferencedataid").HasName("PK__br_artpu__879F18F312880F7F"); j.ToTable("br_artpublication_typecategory"); @@ -3295,7 +3270,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimResearchActivityId, e.DimKeywordId }) - .HasName("PK__dim_rese__F7B536BCE39FD625"); + .HasName("PK__dim_rese__F7B536BC74A2B394"); entity.ToTable("dim_research_activity_dim_keyword"); @@ -3531,7 +3506,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimResearchDatasetId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("dataset-keywords"), j => { - j.HasKey("DimResearchDatasetId", "DimKeywordId").HasName("PK__br_resea__4D226DF25851D3CD"); + j.HasKey("DimResearchDatasetId", "DimKeywordId").HasName("PK__br_resea__4D226DF2CC207043"); j.ToTable("br_research_dataset_dim_keyword"); @@ -3548,7 +3523,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) r => r.HasOne().WithMany().HasForeignKey("DimResearchDatasetId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FKbr_languag34243"), j => { - j.HasKey("DimResearchDatasetId", "DimReferencedataId").HasName("PK__br_langu__576647BF83C8131D"); + j.HasKey("DimResearchDatasetId", "DimReferencedataId").HasName("PK__br_langu__576647BF311D975C"); j.ToTable("br_language_codes_for_datasets"); @@ -3943,7 +3918,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { entity.ToTable("dim_type_of_funding"); - entity.HasIndex(e => e.TypeId, "UQ__dim_type__2C00059913E5EF78") + entity.HasIndex(e => e.TypeId, "UQ__dim_type__2C00059982D178AE") .IsUnique(); entity.Property(e => e.Id).HasColumnName("id"); @@ -4222,7 +4197,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimFundingDecisionId, e.DimOrganizationId, e.DimDateId, e.DimNameId, e.DimPublicationId, e.DimGeoId, e.DimInfrastructureId, e.DimNewsFeedId, e.DimResearchDatasetId, e.DimResearchDataCatalogId, e.DimIdentifierlessDataId, e.DimResearchActivityId, e.DimResearchCommunityId, e.DimReferencedataActorRoleId }) - .HasName("PK__fact_con__B7D7E1B50BA9F19E"); + .HasName("PK__fact_con__B7D7E1B5BE047E62"); entity.ToTable("fact_contribution"); @@ -4364,7 +4339,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimReferencedataId, e.DimResearchDatasetId, e.DimKnownPersonId, e.DimPublicationId, e.DimResearchActivityId, e.DimFundingDecisionId, e.DimInfrastructureId }) - .HasName("PK__fact_dim__3CB15DD36CF1EA12"); + .HasName("PK__fact_dim__3CB15DD39C5754B7"); entity.ToTable("fact_dim_referencedata_field_of_science"); @@ -4421,8 +4396,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasKey(e => new { e.DimUserProfileId, e.DimFieldDisplaySettingsId, e.DimNameId, e.DimWebLinkId, e.DimFundingDecisionId, e.DimPublicationId, e.DimPidId, e.DimPidIdOrcidPutCode, e.DimResearchActivityId, e.DimEventId, e.DimEducationId, e.DimCompetenceId, e.DimResearchCommunityId, e.DimTelephoneNumberId, e.DimEmailAddrressId, e.DimResearcherDescriptionId, e.DimIdentifierlessDataId, e.DimOrcidPublicationId, e.DimKeywordId, e.DimAffiliationId, e.DimResearcherToResearchCommunityId, e.DimResearchDatasetId, e.DimRegisteredDataSourceId, e.DimReferencedataFieldOfScienceId }) - .HasName("PK__fact_fie__93106223BBB1E928"); + entity.HasKey(e => new { e.DimUserProfileId, e.DimFieldDisplaySettingsId, e.DimNameId, e.DimWebLinkId, e.DimFundingDecisionId, e.DimPublicationId, e.DimPidId, e.DimPidIdOrcidPutCode, e.DimResearchActivityId, e.DimEventId, e.DimEducationId, e.DimCompetenceId, e.DimResearchCommunityId, e.DimTelephoneNumberId, e.DimEmailAddrressId, e.DimResearcherDescriptionId, e.DimIdentifierlessDataId, e.DimProfileOnlyPublicationId, e.DimProfileOnlyResearchActivityId, e.DimKeywordId, e.DimAffiliationId, e.DimResearcherToResearchCommunityId, e.DimReferencedataFieldOfScienceId, e.DimResearchDatasetId, e.DimRegisteredDataSourceId, e.DimReferencedataActorRoleId }); entity.ToTable("fact_field_values"); @@ -4460,7 +4434,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.DimIdentifierlessDataId).HasColumnName("dim_identifierless_data_id"); - entity.Property(e => e.DimOrcidPublicationId).HasColumnName("dim_orcid_publication_id"); + entity.Property(e => e.DimProfileOnlyPublicationId).HasColumnName("dim_profile_only_publication_id"); + + entity.Property(e => e.DimProfileOnlyResearchActivityId).HasColumnName("dim_profile_only_research_activity_id"); entity.Property(e => e.DimKeywordId).HasColumnName("dim_keyword_id"); @@ -4468,11 +4444,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.DimResearcherToResearchCommunityId).HasColumnName("dim_researcher_to_research_community_id"); + entity.Property(e => e.DimReferencedataFieldOfScienceId).HasColumnName("dim_referencedata_field_of_science_id"); + entity.Property(e => e.DimResearchDatasetId).HasColumnName("dim_research_dataset_id"); entity.Property(e => e.DimRegisteredDataSourceId).HasColumnName("dim_registered_data_source_id"); - entity.Property(e => e.DimReferencedataFieldOfScienceId).HasColumnName("dim_referencedata_field_of_science_id"); + entity.Property(e => e.DimReferencedataActorRoleId).HasColumnName("dim_referencedata_actor_role_id"); entity.Property(e => e.Created) .HasColumnType("datetime") @@ -4555,12 +4533,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("FKfact_field604813"); - entity.HasOne(d => d.DimOrcidPublication) - .WithMany(p => p.FactFieldValues) - .HasForeignKey(d => d.DimOrcidPublicationId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FKfact_field692932"); - entity.HasOne(d => d.DimPid) .WithMany(p => p.FactFieldValueDimPids) .HasForeignKey(d => d.DimPidId) @@ -4573,14 +4545,32 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("orcid_put_code"); + entity.HasOne(d => d.DimProfileOnlyPublication) + .WithMany(p => p.FactFieldValues) + .HasForeignKey(d => d.DimProfileOnlyPublicationId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKfact_field692932"); + + entity.HasOne(d => d.DimProfileOnlyResearchActivity) + .WithMany(p => p.FactFieldValues) + .HasForeignKey(d => d.DimProfileOnlyResearchActivityId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FKfact_field671081"); + entity.HasOne(d => d.DimPublication) .WithMany(p => p.FactFieldValues) .HasForeignKey(d => d.DimPublicationId) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("displayed publications"); + entity.HasOne(d => d.DimReferencedataActorRole) + .WithMany(p => p.FactFieldValueDimReferencedataActorRoles) + .HasForeignKey(d => d.DimReferencedataActorRoleId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("actor role"); + entity.HasOne(d => d.DimReferencedataFieldOfScience) - .WithMany(p => p.FactFieldValues) + .WithMany(p => p.FactFieldValueDimReferencedataFieldOfSciences) .HasForeignKey(d => d.DimReferencedataFieldOfScienceId) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("FKfact_field192234"); @@ -4643,7 +4633,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimKeywordId, e.DimServiceId, e.DimServicePointId, e.DimInfrastructureId }) - .HasName("PK__fact_inf__3C29B680677C35E2"); + .HasName("PK__fact_inf__3C29B680C8997A0B"); entity.ToTable("fact_infra_keywords"); @@ -4700,7 +4690,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimPublicationChannelId, e.DimReferencedataId, e.Year }) - .HasName("PK__fact_juf__0E099E4BB4E9B8B5"); + .HasName("PK__fact_juf__0E099E4B6E817B2E"); entity.ToTable("fact_jufo_class_codes_for_pub_channels"); @@ -4726,7 +4716,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasKey(e => new { e.DimOrganizationId, e.DimGeoId, e.DimInfrastructureId, e.DimServiceId, e.DimServicePointId, e.DimDateIdStart, e.DimDateIdEnd }) - .HasName("PK__fact_upk__850A8E30B5A84163"); + .HasName("PK__fact_upk__850A8E30113E0064"); entity.ToTable("fact_upkeep"); @@ -4804,138 +4794,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasConstraintName("FKfact_upkee415806"); }); - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("temp_br_infrastructure_dim_field_of_science"); - - entity.Property(e => e.DimFieldOfScienceId).HasColumnName("dim_field_of_science_id"); - - entity.Property(e => e.DimInfrastructureId).HasColumnName("dim_infrastructure_id"); - }); - - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("temp_br_participates_in_funding_group"); - - entity.Property(e => e.DimFundingDecisionid).HasColumnName("dim_funding_decisionid"); - - entity.Property(e => e.DimNameId).HasColumnName("dim_name_id"); - - entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); - - entity.Property(e => e.EndOfParticipation).HasColumnName("end_of_participation"); - - entity.Property(e => e.RoleInFundingGroup) - .HasMaxLength(255) - .HasColumnName("role_in_funding_group"); - - entity.Property(e => e.ShareOfFundingInEur) - .HasColumnType("decimal(18, 2)") - .HasColumnName("share_of_funding_in_EUR"); - - entity.Property(e => e.SourceId) - .HasMaxLength(30) - .HasColumnName("source_id"); - }); - - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("temp_dim_registered_data_source"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); - - entity.Property(e => e.Id) - .ValueGeneratedOnAdd() - .HasColumnName("id"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.Name) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("name"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - }); - - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("temp_dim_registered_data_source_20221121"); - - entity.Property(e => e.Created) - .HasColumnType("datetime") - .HasColumnName("created"); - - entity.Property(e => e.DimOrganizationId).HasColumnName("dim_organization_id"); - - entity.Property(e => e.Id) - .ValueGeneratedOnAdd() - .HasColumnName("id"); - - entity.Property(e => e.Modified) - .HasColumnType("datetime") - .HasColumnName("modified"); - - entity.Property(e => e.Name) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("name"); - - entity.Property(e => e.SourceDescription) - .HasMaxLength(255) - .HasColumnName("source_description"); - - entity.Property(e => e.SourceId) - .IsRequired() - .HasMaxLength(255) - .HasColumnName("source_id"); - }); - - modelBuilder.Entity(entity => - { - entity.HasNoKey(); - - entity.ToTable("temp_fact_dim_referencedata_field_of_science"); - - entity.Property(e => e.DimFundingDecisionId).HasColumnName("dim_funding_decision_id"); - - entity.Property(e => e.DimInfrastructureId).HasColumnName("dim_infrastructure_id"); - - entity.Property(e => e.DimKnownPersonId).HasColumnName("dim_known_person_id"); - - entity.Property(e => e.DimPublicationId).HasColumnName("dim_publication_id"); - - entity.Property(e => e.DimReferencedataId).HasColumnName("dim_referencedata_id"); - - entity.Property(e => e.DimResearchActivityId).HasColumnName("dim_research_activity_id"); - - entity.Property(e => e.DimResearchDatasetId).HasColumnName("dim_research_dataset_id"); - }); - OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } -} +} \ No newline at end of file diff --git a/aspnetcore/src/api/Program.cs b/aspnetcore/src/api/Program.cs index 25ae9736..871af1c4 100644 --- a/aspnetcore/src/api/Program.cs +++ b/aspnetcore/src/api/Program.cs @@ -1,15 +1,19 @@ using System; +using System.Diagnostics; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Serilog; - +using Serilog; + namespace api { public class Program { public static void Main(string[] args) { + // Print Seriog error messages. + Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine($"{msg} (Serilog)")); + var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .AddUserSecrets() @@ -20,18 +24,18 @@ public static void Main(string[] args) .ReadFrom.Configuration(configuration) .CreateLogger(); - try - { - Log.Information("Application starting up"); - CreateHostBuilder(args).Build().Run(); - } - catch (Exception ex) - { - Log.Fatal(ex, "The application start failed."); + try + { + Log.Information("Application starting up"); + CreateHostBuilder(args).Build().Run(); + } + catch (Exception ex) + { + Log.Fatal(ex, "The application start failed."); } finally - { - Log.CloseAndFlush(); + { + Log.CloseAndFlush(); } } diff --git a/aspnetcore/src/api/Services/DuplicateHandlerService.cs b/aspnetcore/src/api/Services/DuplicateHandlerService.cs index 816ceaeb..33fc15ba 100644 --- a/aspnetcore/src/api/Services/DuplicateHandlerService.cs +++ b/aspnetcore/src/api/Services/DuplicateHandlerService.cs @@ -1,5 +1,5 @@  -using System.Collections.Generic; +using System.Collections.Generic; using api.Models.Common; using api.Models.ProfileEditor; using api.Models.ProfileEditor.Items; @@ -23,7 +23,7 @@ public DuplicateHandlerService() */ public bool IsOrcidPublication(ProfileDataFromSql profileData) { - return profileData.FactFieldValues_DimOrcidPublicationId != -1 && profileData.DimFieldDisplaySettings_FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID; + return profileData.FactFieldValues_DimProfileOnlyPublicationId != -1 && profileData.DimFieldDisplaySettings_FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY; } /* @@ -75,7 +75,7 @@ public List AddPublicationToProfileEditorData(ProfileE // Check duplicate publicationId. if ( (!IsOrcidPublication(profileData) && profileData.DimPublication_PublicationId != "" && profileData.DimPublication_PublicationId == publication.PublicationId) || - (IsOrcidPublication(profileData) && profileData.DimOrcidPublication_PublicationId != "" && profileData.DimOrcidPublication_PublicationId == publication.PublicationId) + (IsOrcidPublication(profileData) && profileData.DimProfileOnlyPublication_PublicationId != "" && profileData.DimProfileOnlyPublication_PublicationId == publication.PublicationId) ) { AddDataSource(publication, dataSource); @@ -85,9 +85,9 @@ public List AddPublicationToProfileEditorData(ProfileE // Check duplicate DOI. if ( IsOrcidPublication(profileData) && - profileData.DimOrcidPublication_Doi != "" && - profileData.DimOrcidPublication_Doi == publication.Doi && - !HasSameDoiButIsDifferentPublication(profileData.DimOrcidPublication_PublicationName, publication) + profileData.DimProfileOnlyPublication_Doi != "" && + profileData.DimProfileOnlyPublication_Doi == publication.Doi && + !HasSameDoiButIsDifferentPublication(profileData.DimProfileOnlyPublication_PublicationName, publication) ) { AddDataSource(publication, dataSource); @@ -128,10 +128,10 @@ public List AddPublicationToProfileEditorData(ProfileE publications.Add( new ProfileEditorPublication() { - PublicationId = profileData.DimOrcidPublication_PublicationId, - PublicationName = profileData.DimOrcidPublication_PublicationName, - PublicationYear = HandlePublicationYear(profileData.DimOrcidPublication_PublicationYear), - Doi = profileData.DimOrcidPublication_Doi, + PublicationId = profileData.DimProfileOnlyPublication_PublicationId, + PublicationName = profileData.DimProfileOnlyPublication_PublicationName, + PublicationYear = HandlePublicationYear(profileData.DimProfileOnlyPublication_PublicationYear), + Doi = profileData.DimProfileOnlyPublication_Doi, AuthorsText = "", TypeCode = "", JournalName = "", @@ -139,8 +139,8 @@ public List AddPublicationToProfileEditorData(ProfileE ParentPublicationName = "", itemMeta = new ProfileEditorItemMeta() { - Id = profileData.FactFieldValues_DimOrcidPublicationId, - Type = Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID, + Id = profileData.FactFieldValues_DimProfileOnlyPublicationId, + Type = Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY, Show = profileData.FactFieldValues_Show, PrimaryValue = profileData.FactFieldValues_PrimaryValue }, diff --git a/aspnetcore/src/api/Services/ITtvSqlService.cs b/aspnetcore/src/api/Services/ITtvSqlService.cs index a7ce621b..82474f19 100644 --- a/aspnetcore/src/api/Services/ITtvSqlService.cs +++ b/aspnetcore/src/api/Services/ITtvSqlService.cs @@ -20,7 +20,7 @@ public interface ITtvSqlService string GetSqlQuery_Delete_DimIdentifierlessData_Parent(int id); string GetSqlQuery_Delete_DimKeyword(List dimKeywordIds); string GetSqlQuery_Delete_DimNames(List dimNameIds); - string GetSqlQuery_Delete_DimOrcidPublications(List dimOrcidPublicationIds); + string GetSqlQuery_Delete_DimProfileOnlyPublications(List dimProfileOnlyPublicationIds); string GetSqlQuery_Delete_DimPids(List dimPidIds); string GetSqlQuery_Delete_DimResearchActivities(List dimResearchActivityIds); string GetSqlQuery_Delete_DimResearchCommunities(List dimResearchCommunityIds); diff --git a/aspnetcore/src/api/Services/IUserProfileService.cs b/aspnetcore/src/api/Services/IUserProfileService.cs index 18f7793b..8e8ac1b8 100644 --- a/aspnetcore/src/api/Services/IUserProfileService.cs +++ b/aspnetcore/src/api/Services/IUserProfileService.cs @@ -18,7 +18,7 @@ public interface IUserProfileService Task CreateProfile(string orcidId, LogUserIdentification logUserIdentification); Task DeleteProfileDataAsync(int userprofileId, LogUserIdentification logUserIdentification); Task ExecuteRawSql(string sql); - DimOrcidPublication GetEmptyDimOrcidPublication(); + DimProfileOnlyPublication GetEmptyDimProfileOnlyPublication(); DimPid GetEmptyDimPid(); FactFieldValue GetEmptyFactFieldValue(); FactFieldValue GetEmptyFactFieldValueDemo(); diff --git a/aspnetcore/src/api/Services/OrcidImportService.cs b/aspnetcore/src/api/Services/OrcidImportService.cs index 14c901a8..91ac4973 100644 --- a/aspnetcore/src/api/Services/OrcidImportService.cs +++ b/aspnetcore/src/api/Services/OrcidImportService.cs @@ -1,12 +1,20 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Mail; using System.Threading.Tasks; +using api.Controllers; using api.Models.Common; using api.Models.Orcid; using api.Models.Ttv; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.Extensions.Logging; +using Nest; +using Serilog.Core; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory; +using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource; +using Constants = api.Models.Common.Constants; namespace api.Services { @@ -21,9 +29,11 @@ public class OrcidImportService : IOrcidImportService private readonly IOrganizationHandlerService _organizationHandlerService; private readonly IDataSourceHelperService _dataSourceHelperService; private readonly IUtilityService _utilityService; + private readonly ILogger _logger; public OrcidImportService(TtvContext ttvContext, IUserProfileService userProfileService, IOrcidJsonParserService orcidJsonParserService, - IOrganizationHandlerService organizationHandlerService, IUtilityService utilityService, IDataSourceHelperService dataSourceHelperService) + IOrganizationHandlerService organizationHandlerService, IUtilityService utilityService, IDataSourceHelperService dataSourceHelperService, + ILogger logger) { _ttvContext = ttvContext; _userProfileService = userProfileService; @@ -31,11 +41,12 @@ public OrcidImportService(TtvContext ttvContext, IUserProfileService userProfile _organizationHandlerService = organizationHandlerService; _utilityService = utilityService; _dataSourceHelperService = dataSourceHelperService; + _logger = logger; } /* - * Add DimDates + * Add DimDates entities needed in ORCID record. */ public async Task AddDimDates(string orcidRecordJson, DateTime currentDateTime) { @@ -44,7 +55,11 @@ public async Task AddDimDates(string orcidRecordJson, DateTime currentDateTime) foreach (OrcidEducation education in educations) { // Start date - DimDate educationStartDate = await _ttvContext.DimDates.FirstOrDefaultAsync(dd => dd.Year == education.StartDate.Year && dd.Month == education.StartDate.Month && dd.Day == education.StartDate.Day); + DimDate educationStartDate = + await _ttvContext.DimDates.FirstOrDefaultAsync( + dd => dd.Year == education.StartDate.Year && + dd.Month == education.StartDate.Month && + dd.Day == education.StartDate.Day); if (educationStartDate == null) { educationStartDate = new DimDate() @@ -62,7 +77,11 @@ public async Task AddDimDates(string orcidRecordJson, DateTime currentDateTime) } // End date - DimDate educationEndDate = await _ttvContext.DimDates.FirstOrDefaultAsync(ed => ed.Year == education.EndDate.Year && ed.Month == education.EndDate.Month && ed.Day == education.EndDate.Day); + DimDate educationEndDate = + await _ttvContext.DimDates.FirstOrDefaultAsync( + ed => ed.Year == education.EndDate.Year && + ed.Month == education.EndDate.Month && + ed.Day == education.EndDate.Day); if (educationEndDate == null) { educationEndDate = new DimDate() @@ -85,7 +104,11 @@ public async Task AddDimDates(string orcidRecordJson, DateTime currentDateTime) foreach (OrcidEmployment employment in employments) { // Start date - DimDate employmentStartDate = await _ttvContext.DimDates.FirstOrDefaultAsync(dd => dd.Year == employment.StartDate.Year && dd.Month == employment.StartDate.Month && dd.Day == employment.StartDate.Day); + DimDate employmentStartDate = + await _ttvContext.DimDates.FirstOrDefaultAsync( + dd => dd.Year == employment.StartDate.Year && + dd.Month == employment.StartDate.Month && + dd.Day == employment.StartDate.Day); if (employmentStartDate == null) { employmentStartDate = new DimDate() @@ -103,7 +126,10 @@ public async Task AddDimDates(string orcidRecordJson, DateTime currentDateTime) } // End date - DimDate employmentEndDate = await _ttvContext.DimDates.FirstOrDefaultAsync(dd => dd.Year == employment.EndDate.Year && dd.Month == employment.EndDate.Month && dd.Day == employment.EndDate.Day); + DimDate employmentEndDate = await _ttvContext.DimDates.FirstOrDefaultAsync( + dd => dd.Year == employment.EndDate.Year && + dd.Month == employment.EndDate.Month && + dd.Day == employment.EndDate.Day); if (employmentEndDate == null) { employmentEndDate = new DimDate() @@ -132,35 +158,42 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, int orcidRegisteredDataSourceId = _dataSourceHelperService.DimRegisteredDataSourceId_ORCID; // Get DimUserProfile and related entities - DimUserProfile dimUserProfile = await _ttvContext.DimUserProfiles.TagWith("Insert ORCID data").Where(dup => dup.Id == userprofileId) + string queryTag = $"Insert ORCID data, dim_user_profile.id={userprofileId}"; + DimUserProfile dimUserProfile = await _ttvContext.DimUserProfiles.TagWith(queryTag).Where(dup => dup.Id == userprofileId) .Include(dup => dup.DimFieldDisplaySettings) + // DimRegisteredDataSource .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimRegisteredDataSource) .ThenInclude(drds => drds.DimOrganization) + // DimName .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimName) + // DimWebLink .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimWebLink) + // DimFundingDecision .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimFundingDecision) - //.Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) - // .ThenInclude(ffv => ffv.DimPublication) + // DimProfileOnlyPublication .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) - .ThenInclude(ffv => ffv.DimOrcidPublication) + .ThenInclude(ffv => ffv.DimProfileOnlyPublication) + // DimPid .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimPid) + // DimPidIdOrcidPutCodeNavigation .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimPidIdOrcidPutCodeNavigation) + // DimResearchActivity .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimResearchActivity) - //.Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) - // .ThenInclude(ffv => ffv.DimEvent) + // DimEducation .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimEducation) .ThenInclude(de => de.DimStartDateNavigation) .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimEducation) .ThenInclude(de => de.DimEndDateNavigation) + // DimAffiliation .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimAffiliation) .ThenInclude(da => da.DimOrganization) @@ -170,19 +203,20 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimAffiliation) .ThenInclude(da => da.EndDateNavigation) - //.Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) - // .ThenInclude(ffv => ffv.DimCompetence) - //.Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) - // .ThenInclude(ffv => ffv.DimResearchCommunity) + // DimTelephoneNumber .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimTelephoneNumber) + // DimEmailAddrress .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimEmailAddrress) + // DimResearcherDescription .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimResearcherDescription) + // DimIdentifierlessData .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimIdentifierlessData) .ThenInclude(did => did.InverseDimIdentifierlessData) // DimIdentifierlessData can have a child entity. + // DimKeyword .Include(dup => dup.FactFieldValues.Where(ffv => ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId)) .ThenInclude(ffv => ffv.DimKeyword).FirstOrDefaultAsync(); @@ -192,22 +226,27 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Add DimDates. await AddDimDates(orcidRecordJson, currentDateTime); + // Helper object to store processed IDs, used when deciding what data needs to be removed. + OrcidImportHelper orcidImportHelper = new(); + // Name DimFieldDisplaySetting dimFieldDisplaySettingsName = dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dimFieldDisplaysettingsName => dimFieldDisplaysettingsName.FieldIdentifier == Constants.FieldIdentifiers.PERSON_NAME); // FactFieldValues FactFieldValue factFieldValuesName = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimFieldDisplaySettings.Id == dimFieldDisplaySettingsName.Id && ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId); + dimUserProfile.FactFieldValues.FirstOrDefault( + ffv => ffv.DimFieldDisplaySettings.Id == dimFieldDisplaySettingsName.Id && ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId); if (factFieldValuesName != null) { // Update existing DimName DimName dimName = factFieldValuesName.DimName; dimName.LastName = _orcidJsonParserService.GetFamilyName(orcidRecordJson).Value; dimName.FirstNames = _orcidJsonParserService.GetGivenNames(orcidRecordJson).Value; - dimName.Modified = _utilityService.GetCurrentDateTime(); + dimName.Modified = currentDateTime; // Update existing FactFieldValue - factFieldValuesName.Show = true; // ORCID name is selected by default. factFieldValuesName.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimNameIds.Add(factFieldValuesName.DimName.Id); } else { @@ -230,18 +269,24 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, factFieldValuesName.DimFieldDisplaySettings = dimFieldDisplaySettingsName; factFieldValuesName.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; factFieldValuesName.DimName = dimName; - factFieldValuesName.Show = true; + factFieldValuesName.Show = true; // ORCID name is selected by default. _ttvContext.FactFieldValues.Add(factFieldValuesName); } // Other names List otherNames = _orcidJsonParserService.GetOtherNames(orcidRecordJson); + // Get DimFieldDisplaySettings for other name + DimFieldDisplaySetting dimFieldDisplaySettingsOtherName = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsOtherName => dfdsOtherName.FieldIdentifier == Constants.FieldIdentifiers.PERSON_OTHER_NAMES); foreach (OrcidOtherName otherName in otherNames) { // Check if FactFieldValues contains entry, which points to ORCID put code value in DimPid FactFieldValue factFieldValuesOtherName = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == otherName.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsOtherName && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == otherName.PutCode.Value.ToString()); if (factFieldValuesOtherName != null) { @@ -251,6 +296,8 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimName_otherName.Modified = currentDateTime; // Update existing FactFieldValue factFieldValuesOtherName.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimNameIds.Add(factFieldValuesOtherName.DimName.Id); } else { @@ -275,10 +322,6 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimPidOrcidPutCodeOtherName.SourceId = Constants.SourceIdentifiers.PROFILE_API; _ttvContext.DimPids.Add(dimPidOrcidPutCodeOtherName); - // Get DimFieldDisplaySettings for other name - DimFieldDisplaySetting dimFieldDisplaySettingsOtherName = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsWebLink => dfdsWebLink.FieldIdentifier == Constants.FieldIdentifiers.PERSON_OTHER_NAMES); - // Create FactFieldValues for other name factFieldValuesOtherName = _userProfileService.GetEmptyFactFieldValue(); factFieldValuesOtherName.DimUserProfile = dimUserProfile; @@ -293,11 +336,17 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Researcher urls List researcherUrls = _orcidJsonParserService.GetResearcherUrls(orcidRecordJson); + // Get DimFieldDisplaySettings for weblink + DimFieldDisplaySetting dimFieldDisplaySettingsWebLink = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsWebLink => dfdsWebLink.FieldIdentifier == Constants.FieldIdentifiers.PERSON_WEB_LINK); foreach (OrcidResearcherUrl researchUrl in researcherUrls) { // Check if FactFieldValues contains entry, which points to ORCID put code value in DimPid FactFieldValue factFieldValuesWebLink = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == researchUrl.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsWebLink && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == researchUrl.PutCode.Value.ToString()); if (factFieldValuesWebLink != null) { @@ -306,9 +355,10 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimWebLink.Url = researchUrl.Url; dimWebLink.LinkLabel = researchUrl.UrlName; dimWebLink.Modified = currentDateTime; - // Update existing FactFieldValue factFieldValuesWebLink.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimWebLinkIds.Add(factFieldValuesWebLink.DimWebLink.Id); } else { @@ -336,10 +386,6 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimPidOrcidPutCodeWebLink.SourceId = Constants.SourceIdentifiers.PROFILE_API; _ttvContext.DimPids.Add(dimPidOrcidPutCodeWebLink); - // Get DimFieldDisplaySettings for weblink - DimFieldDisplaySetting dimFieldDisplaySettingsWebLink = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsWebLink => dfdsWebLink.FieldIdentifier == Constants.FieldIdentifiers.PERSON_WEB_LINK); - // Create FactFieldValues for weblink factFieldValuesWebLink = _userProfileService.GetEmptyFactFieldValue(); factFieldValuesWebLink.DimUserProfile = dimUserProfile; @@ -354,71 +400,116 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Researcher description OrcidBiography biography = _orcidJsonParserService.GetBiography(orcidRecordJson); + // Get DimFieldDisplaySettings for researcher description + DimFieldDisplaySetting dimFieldDisplaySettingsResearcherDescription = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault( + dimFieldDisplaySettingsResearcherDescription => dimFieldDisplaySettingsResearcherDescription.FieldIdentifier == Constants.FieldIdentifiers.PERSON_RESEARCHER_DESCRIPTION); if (biography != null) { - DimResearcherDescription dimResearcherDescription = await _userProfileService.AddOrUpdateDimResearcherDescription( - "", - _orcidJsonParserService.GetBiography(orcidRecordJson).Value, - "", - dimUserProfile.DimKnownPersonId, - orcidRegisteredDataSourceId - ); - - // Researcher description: DimFieldDisplaySettings - DimFieldDisplaySetting dimFieldDisplaySettingsResearcherDescription = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault( - dimFieldDisplaySettingsResearcherDescription => dimFieldDisplaySettingsResearcherDescription.FieldIdentifier == Constants.FieldIdentifiers.PERSON_RESEARCHER_DESCRIPTION - ); - - // Researcher description: FactFieldValues - FactFieldValue factFieldValuesResearcherDescription = dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimResearcherDescriptionId == dimResearcherDescription.Id); - if (factFieldValuesResearcherDescription == null) + // Check if FactFieldValues contains entry pointing to DimResearcherDescriptions, which has ORCID as data source + FactFieldValue factFieldValuesResearcherDescription = + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsResearcherDescription && + ffv.DimResearcherDescriptionId > 0 && + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId); + + if (factFieldValuesResearcherDescription != null) { + // Update existing DimResearcherDescription + factFieldValuesResearcherDescription.DimResearcherDescription.ResearchDescriptionEn = biography.Value; + factFieldValuesResearcherDescription.DimResearcherDescription.Modified = currentDateTime; + // Update existing FactFieldValue + factFieldValuesResearcherDescription.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimResearcherDescriptionIds.Add(factFieldValuesResearcherDescription.DimResearcherDescription.Id); + } + else + { // Create new DimResearcherDescription + DimResearcherDescription dimResearcherDescription = new () + { + ResearchDescriptionFi = "", + ResearchDescriptionEn = biography.Value, + ResearchDescriptionSv = "", + SourceId = Constants.SourceIdentifiers.PROFILE_API, + SourceDescription = Constants.SourceDescriptions.PROFILE_API, + Created = currentDateTime, + Modified = currentDateTime, + DimKnownPersonId = dimUserProfile.DimKnownPersonId, + DimRegisteredDataSourceId = orcidRegisteredDataSourceId + }; + _ttvContext.DimResearcherDescriptions.Add(dimResearcherDescription); + + // Create FactFieldValues for researcher description factFieldValuesResearcherDescription = _userProfileService.GetEmptyFactFieldValue(); factFieldValuesResearcherDescription.DimUserProfile = dimUserProfile; factFieldValuesResearcherDescription.DimFieldDisplaySettings = dimFieldDisplaySettingsResearcherDescription; - factFieldValuesResearcherDescription.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; factFieldValuesResearcherDescription.DimResearcherDescription = dimResearcherDescription; + factFieldValuesResearcherDescription.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; _ttvContext.FactFieldValues.Add(factFieldValuesResearcherDescription); } - else - { - factFieldValuesResearcherDescription.Modified = currentDateTime; - } } // Email List emails = _orcidJsonParserService.GetEmails(orcidRecordJson); + // Email: DimFieldDisplaySettings + DimFieldDisplaySetting dimFieldDisplaySettingsEmailAddress = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault( + dimFieldDisplaySettingsEmailAddress => dimFieldDisplaySettingsEmailAddress.FieldIdentifier == Constants.FieldIdentifiers.PERSON_EMAIL_ADDRESS); foreach (OrcidEmail email in emails) { - // Email: DimEmailAddrressess - DimEmailAddrress dimEmailAddress = await _userProfileService.AddOrUpdateDimEmailAddress( - email.Value, - dimUserProfile.DimKnownPersonId, - orcidRegisteredDataSourceId - ); - - // Email: DimFieldDisplaySettings - DimFieldDisplaySetting dimFieldDisplaySettingsEmailAddress = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault( - dimFieldDisplaySettingsEmailAddress => dimFieldDisplaySettingsEmailAddress.FieldIdentifier == Constants.FieldIdentifiers.PERSON_EMAIL_ADDRESS - ); + // Check if email already exists + FactFieldValue factFieldValuesEmail = + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsEmailAddress && + ffv.DimEmailAddrress.Email == email.Value); - // Email: FactFieldValues - FactFieldValue factFieldValuesEmailAddress = dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimEmailAddrressId == dimEmailAddress.Id); - if (factFieldValuesEmailAddress == null) + if (factFieldValuesEmail != null) { - factFieldValuesEmailAddress = _userProfileService.GetEmptyFactFieldValue(); - factFieldValuesEmailAddress.DimUserProfile = dimUserProfile; - factFieldValuesEmailAddress.DimFieldDisplaySettings = dimFieldDisplaySettingsEmailAddress; - factFieldValuesEmailAddress.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; - factFieldValuesEmailAddress.DimEmailAddrress = dimEmailAddress; - _ttvContext.FactFieldValues.Add(factFieldValuesEmailAddress); + // Email address is matched by value, so no modification is made here. + + // Update existing FactFieldValue + factFieldValuesEmail.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimEmailAddressIds.Add(factFieldValuesEmail.DimEmailAddrressId); } else { - factFieldValuesEmailAddress.Modified = currentDateTime; + // Create new DimEmailAddrress + DimEmailAddrress dimEmailAddress = new() + { + Email = email.Value, + SourceId = Constants.SourceIdentifiers.PROFILE_API, + SourceDescription = Constants.SourceDescriptions.PROFILE_API, + Created = currentDateTime, + Modified = currentDateTime, + DimKnownPersonId = dimUserProfile.DimKnownPersonId, + DimRegisteredDataSourceId = orcidRegisteredDataSourceId + }; + _ttvContext.DimEmailAddrresses.Add(dimEmailAddress); + + // Email: FactFieldValues + factFieldValuesEmail = _userProfileService.GetEmptyFactFieldValue(); + factFieldValuesEmail.DimUserProfile = dimUserProfile; + factFieldValuesEmail.DimFieldDisplaySettings = dimFieldDisplaySettingsEmailAddress; + factFieldValuesEmail.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; + factFieldValuesEmail.DimEmailAddrress = dimEmailAddress; + + // Add email address ORCID put code into DimPid. + // In ORCID data the email has field put code, but it seems to be always null. + if (email.PutCode.Value != null) + { + DimPid dimPidOrcidPutCodeEmail = _userProfileService.GetEmptyDimPid(); + dimPidOrcidPutCodeEmail.PidContent = email.PutCode.GetDbValue(); + dimPidOrcidPutCodeEmail.PidType = Constants.PidTypes.ORCID_PUT_CODE; + dimPidOrcidPutCodeEmail.DimKnownPersonId = dimUserProfile.DimKnownPersonId; + dimPidOrcidPutCodeEmail.SourceId = Constants.SourceIdentifiers.PROFILE_API; + _ttvContext.DimPids.Add(dimPidOrcidPutCodeEmail); + + factFieldValuesEmail.DimPidIdOrcidPutCodeNavigation = dimPidOrcidPutCodeEmail; + } + + _ttvContext.FactFieldValues.Add(factFieldValuesEmail); } } @@ -434,7 +525,10 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, { // Check if FactFieldValues contains entry, which points to ORCID put code value in DimKeyword FactFieldValue factFieldValuesKeyword = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == keyword.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsKeyword && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == keyword.PutCode.Value.ToString()); if (factFieldValuesKeyword != null) { @@ -444,6 +538,8 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimKeyword.Modified = currentDateTime; // Update existing FactFieldValue factFieldValuesKeyword.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimKeywordIds.Add(factFieldValuesKeyword.DimKeywordId); } else { @@ -478,15 +574,7 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, } processedKeywordFactFieldValues.Add(factFieldValuesKeyword); } - // Remove existing keywords which were not in ORCID data. - foreach (FactFieldValue ffvKeyword in dimFieldDisplaySettingsKeyword.FactFieldValues) - { - if (!processedKeywordFactFieldValues.Contains(ffvKeyword)) - { - _ttvContext.FactFieldValues.Remove(ffvKeyword); - _ttvContext.DimKeywords.Remove(ffvKeyword.DimKeyword); - } - } + // External identifier (=DimPid) @@ -498,7 +586,10 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, { // Check if FactFieldValues contains entry, which points to ORCID put code value in DimPid FactFieldValue factFieldValuesExternalIdentifier = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == externalIdentifier.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsExternalIdentifier && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == externalIdentifier.PutCode.Value.ToString()); if (factFieldValuesExternalIdentifier != null) { @@ -509,6 +600,8 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimPid.Modified = currentDateTime; // Update existing FactFieldValue factFieldValuesExternalIdentifier.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimPidIds.Add(factFieldValuesExternalIdentifier.DimPidId); } else { @@ -542,11 +635,17 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Education List educations = _orcidJsonParserService.GetEducations(orcidRecordJson); + // Get DimFieldDisplaySettings for education + DimFieldDisplaySetting dimFieldDisplaySettingsEducation = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsEducation => dfdsEducation.FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_EDUCATION); foreach (OrcidEducation education in educations) { // Check if FactFieldValues contains entry, which points to ORCID put code value in DimEducation FactFieldValue factFieldValuesEducation = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == education.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsEducation && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == education.PutCode.Value.ToString()); // Start date DimDate educationStartDate = await _ttvContext.DimDates @@ -565,9 +664,10 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimEducation.DimStartDateNavigation = educationStartDate; dimEducation.DimEndDateNavigation = educationEndDate; dimEducation.Modified = currentDateTime; - // Update existing FactFieldValue factFieldValuesEducation.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimEducationIds.Add(factFieldValuesEducation.DimEducationId); } else { @@ -595,10 +695,6 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimPidOrcidPutCodeEducation.SourceId = Constants.SourceIdentifiers.PROFILE_API; _ttvContext.DimPids.Add(dimPidOrcidPutCodeEducation); - // Get DimFieldDisplaySettings for education - DimFieldDisplaySetting dimFieldDisplaySettingsEducation = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsEducation => dfdsEducation.FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_EDUCATION); - // Create FactFieldValues for education factFieldValuesEducation = _userProfileService.GetEmptyFactFieldValue(); factFieldValuesEducation.DimUserProfile = dimUserProfile; @@ -614,6 +710,9 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Employment (Affiliation in Ttv database) List employments = _orcidJsonParserService.GetEmployments(orcidRecordJson); + // Get DimFieldDisplaySettings for affiliation + DimFieldDisplaySetting dimFieldDisplaySettingsAffiliation = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsAffiliation => dfdsAffiliation.FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_AFFILIATION); foreach (OrcidEmployment employment in employments) { /* @@ -628,7 +727,10 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Check if FactFieldValues contains entry, which points to ORCID put code value in DimAffiliation FactFieldValue factFieldValuesAffiliation = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == employment.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsAffiliation && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == employment.PutCode.Value.ToString()); // Search organization identifier from DimPid based on ORCID's disambiguated-organization-identifier data. int? dimOrganization_id_affiliation = await _organizationHandlerService.FindOrganizationIdByOrcidDisambiguationIdentifier( @@ -703,6 +805,9 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Update modified timestamp in FactFieldValue factFieldValuesAffiliation.Modified = currentDateTime; + + // Mark as processed + orcidImportHelper.dimAffiliationIds.Add(factFieldValuesAffiliation.DimAffiliationId); } else { @@ -740,10 +845,6 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimPidOrcidPutCodeEmployment.SourceId = Constants.SourceIdentifiers.PROFILE_API; _ttvContext.DimPids.Add(dimPidOrcidPutCodeEmployment); - // Get DimFieldDisplaySettings for affiliation - DimFieldDisplaySetting dimFieldDisplaySettingsAffiliation = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsAffiliation => dfdsAffiliation.FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_AFFILIATION); - // Create FactFieldValues for affiliation factFieldValuesAffiliation = _userProfileService.GetEmptyFactFieldValue(); factFieldValuesAffiliation.DimUserProfile = dimUserProfile; @@ -767,7 +868,7 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, /* * Affiliation department name handling */ - if (employment.DepartmentName != "") + if (!string.IsNullOrWhiteSpace(employment.DepartmentName)) { // ORCID employment contains 'department-name' @@ -836,36 +937,44 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, // Publication List orcidPublications = _orcidJsonParserService.GetPublications(orcidRecordJson); + // Get DimFieldDisplaySettings for orcid publication + DimFieldDisplaySetting dimFieldDisplaySettingsOrcidPublication = + dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsPublication => dfdsPublication.FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY); foreach (OrcidPublication orcidPublication in orcidPublications) { // Check if FactFieldValues contains entry, which points to ORCID put code value in DimOrcidPublication FactFieldValue factFieldValuesPublication = - dimUserProfile.FactFieldValues.FirstOrDefault(ffv => ffv.DimPidIdOrcidPutCode > 0 && ffv.DimPidIdOrcidPutCodeNavigation.PidContent == orcidPublication.PutCode.Value.ToString()); + dimUserProfile.FactFieldValues.FirstOrDefault(ffv => + ffv.DimFieldDisplaySettings == dimFieldDisplaySettingsOrcidPublication && + ffv.DimPidIdOrcidPutCode > 0 && + ffv.DimPidIdOrcidPutCodeNavigation.PidContent == orcidPublication.PutCode.Value.ToString()); if (factFieldValuesPublication != null) { - // Update existing DimOrcidPublication - DimOrcidPublication dimOrcidPublication = factFieldValuesPublication.DimOrcidPublication; - dimOrcidPublication.OrcidWorkType = orcidPublication.Type; - dimOrcidPublication.PublicationName = orcidPublication.PublicationName; - dimOrcidPublication.PublicationYear = orcidPublication.PublicationYear; - dimOrcidPublication.DoiHandle = orcidPublication.Doi; - dimOrcidPublication.Modified = currentDateTime; + // Update existing DimProfileOnlyPublication + DimProfileOnlyPublication dimProfileOnlyPublication = factFieldValuesPublication.DimProfileOnlyPublication; + dimProfileOnlyPublication.OrcidWorkType = orcidPublication.Type; + dimProfileOnlyPublication.PublicationName = orcidPublication.PublicationName; + dimProfileOnlyPublication.PublicationYear = orcidPublication.PublicationYear; + dimProfileOnlyPublication.DoiHandle = orcidPublication.Doi; + dimProfileOnlyPublication.Modified = currentDateTime; // Update existing FactFieldValue factFieldValuesPublication.Modified = currentDateTime; + // Mark as processed + orcidImportHelper.dimPublicationIds.Add(factFieldValuesPublication.DimProfileOnlyPublicationId); } else { - // Create new DimOrcidPublication - DimOrcidPublication dimOrcidPublication = _userProfileService.GetEmptyDimOrcidPublication(); - dimOrcidPublication.OrcidWorkType = orcidPublication.Type; - dimOrcidPublication.PublicationName = orcidPublication.PublicationName; - dimOrcidPublication.PublicationYear = orcidPublication.PublicationYear; - dimOrcidPublication.DoiHandle = orcidPublication.Doi; - dimOrcidPublication.SourceId = Constants.SourceIdentifiers.PROFILE_API; - dimOrcidPublication.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; - dimOrcidPublication.Created = currentDateTime; - _ttvContext.DimOrcidPublications.Add(dimOrcidPublication); + // Create new DimProfileOnlyPublication + DimProfileOnlyPublication dimProfileOnlyPublication = _userProfileService.GetEmptyDimProfileOnlyPublication(); + dimProfileOnlyPublication.OrcidWorkType = orcidPublication.Type; + dimProfileOnlyPublication.PublicationName = orcidPublication.PublicationName; + dimProfileOnlyPublication.PublicationYear = orcidPublication.PublicationYear; + dimProfileOnlyPublication.DoiHandle = orcidPublication.Doi; + dimProfileOnlyPublication.SourceId = Constants.SourceIdentifiers.PROFILE_API; + dimProfileOnlyPublication.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; + dimProfileOnlyPublication.Created = currentDateTime; + _ttvContext.DimProfileOnlyPublications.Add(dimProfileOnlyPublication); // Add publication's ORCID put code into DimPid DimPid dimPidOrcidPutCodePublication = _userProfileService.GetEmptyDimPid(); @@ -875,23 +984,179 @@ public async Task ImportOrcidRecordJsonIntoUserProfile(int userprofileId, dimPidOrcidPutCodePublication.SourceId = Constants.SourceIdentifiers.PROFILE_API; _ttvContext.DimPids.Add(dimPidOrcidPutCodePublication); - // Get DimFieldDisplaySettings for orcid publication - DimFieldDisplaySetting dimFieldDisplaySettingsOrcidPublication = - dimUserProfile.DimFieldDisplaySettings.FirstOrDefault(dfdsPublication => dfdsPublication.FieldIdentifier == Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID); - // Create FactFieldValues for orcid publication factFieldValuesPublication = _userProfileService.GetEmptyFactFieldValue(); factFieldValuesPublication.DimUserProfile = dimUserProfile; factFieldValuesPublication.DimFieldDisplaySettings = dimFieldDisplaySettingsOrcidPublication; factFieldValuesPublication.DimRegisteredDataSourceId = orcidRegisteredDataSourceId; - factFieldValuesPublication.DimOrcidPublication = dimOrcidPublication; + factFieldValuesPublication.DimProfileOnlyPublication = dimProfileOnlyPublication; factFieldValuesPublication.DimPidIdOrcidPutCodeNavigation = dimPidOrcidPutCodePublication; _ttvContext.FactFieldValues.Add(factFieldValuesPublication); } } - await _ttvContext.SaveChangesAsync(); - return true; + // Remove names, which user has deleted in ORCID + List removableFfvDimNames = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimNameId > 0 && + !orcidImportHelper.dimNameIds.Contains(ffv.DimNameId)).ToList(); + foreach (FactFieldValue removableFfvDimName in removableFfvDimNames.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvDimName); + _ttvContext.DimNames.Remove(removableFfvDimName.DimName); + if (removableFfvDimName.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvDimName.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove web links, which user has deleted in ORCID + List removableFfvWebLinks = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimWebLinkId > 0 && + !orcidImportHelper.dimWebLinkIds.Contains(ffv.DimWebLinkId)).ToList(); + foreach (FactFieldValue removableFfvWebLink in removableFfvWebLinks.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvWebLink); + _ttvContext.DimWebLinks.Remove(removableFfvWebLink.DimWebLink); + if (removableFfvWebLink.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvWebLink.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove researcher descriptions, which user has deleted in ORCID + List removableFfvResearcherDescriptions = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimResearcherDescriptionId > 0 && + !orcidImportHelper.dimResearcherDescriptionIds.Contains(ffv.DimResearcherDescriptionId)).ToList(); + foreach (FactFieldValue removableFfvResearcherDescription in removableFfvResearcherDescriptions.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvResearcherDescription); + _ttvContext.DimResearcherDescriptions.Remove(removableFfvResearcherDescription.DimResearcherDescription); + if (removableFfvResearcherDescription.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvResearcherDescription.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove email addresses, which user has deleted in ORCID + List removableFfvEmails = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimEmailAddrressId > 0 && + !orcidImportHelper.dimEmailAddressIds.Contains(ffv.DimEmailAddrressId)).ToList(); + foreach (FactFieldValue removableFfvEmail in removableFfvEmails.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvEmail); + _ttvContext.DimEmailAddrresses.Remove(removableFfvEmail.DimEmailAddrress); + if (removableFfvEmail.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvEmail.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove keywords, which user has deleted in ORCID + List removableFfvKeywords = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimKeywordId > 0 && + !orcidImportHelper.dimKeywordIds.Contains(ffv.DimKeywordId)).ToList(); + foreach (FactFieldValue removableFfvKeyword in removableFfvKeywords.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvKeyword); + _ttvContext.DimKeywords.Remove(removableFfvKeyword.DimKeyword); + if (removableFfvKeyword.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvKeyword.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove external identifiers, which user has deleted in ORCID + List removableFfvExternalIdentifiers = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimPidId > 0 && + !orcidImportHelper.dimPidIds.Contains(ffv.DimPidId)).ToList(); + foreach (FactFieldValue removableFfvExternalIdentifier in removableFfvExternalIdentifiers.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvExternalIdentifier); + _ttvContext.DimPids.Remove(removableFfvExternalIdentifier.DimPid); + if (removableFfvExternalIdentifier.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvExternalIdentifier.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove educations, which user has deleted in ORCID + List removableFfvEducations = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimEducationId > 0 && + !orcidImportHelper.dimEducationIds.Contains(ffv.DimEducationId)).ToList(); + foreach (FactFieldValue removableFfvEducation in removableFfvEducations.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvEducation); + _ttvContext.DimEducations.Remove(removableFfvEducation.DimEducation); + if (removableFfvEducation.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvEducation.DimPidIdOrcidPutCodeNavigation); + } + } + + // Remove affiliations, which user has deleted in ORCID + List removableFfvAffiliations = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimAffiliationId > 0 && + !orcidImportHelper.dimAffiliationIds.Contains(ffv.DimAffiliationId)).ToList(); + foreach (FactFieldValue removableFfvAffiliation in removableFfvAffiliations.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvAffiliation); + _ttvContext.DimAffiliations.Remove(removableFfvAffiliation.DimAffiliation); + if (removableFfvAffiliation.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvAffiliation.DimPidIdOrcidPutCodeNavigation); + } + // Affiliation organization can be stored in DimIdentifierlessData + if (removableFfvAffiliation.DimIdentifierlessDataId > 0) + { + // DimIdentifierlessData can have child entity + _ttvContext.DimIdentifierlessData.RemoveRange(removableFfvAffiliation.DimIdentifierlessData.InverseDimIdentifierlessData); + _ttvContext.DimIdentifierlessData.Remove(removableFfvAffiliation.DimIdentifierlessData); + } + } + + // Remove publications, which user has deleted in ORCID + List removableFfvPublications = + dimUserProfile.FactFieldValues.Where(ffv => + ffv.DimRegisteredDataSourceId == orcidRegisteredDataSourceId && + ffv.DimProfileOnlyPublicationId > 0 && + !orcidImportHelper.dimPublicationIds.Contains(ffv.DimProfileOnlyPublicationId)).ToList(); + foreach (FactFieldValue removableFfvPublication in removableFfvPublications.Distinct()) + { + _ttvContext.FactFieldValues.Remove(removableFfvPublication); + _ttvContext.DimProfileOnlyPublications.Remove(removableFfvPublication.DimProfileOnlyPublication); + if (removableFfvPublication.DimPidIdOrcidPutCode > 0) + { + _ttvContext.DimPids.Remove(removableFfvPublication.DimPidIdOrcidPutCodeNavigation); + } + } + + try + { + await _ttvContext.SaveChangesAsync(); + return true; + } + catch (Exception ex) + { + _logger.LogError($"ORCID import failed for dim_user_profile.id={userprofileId}: {ex}"); + } + + return false; } } } \ No newline at end of file diff --git a/aspnetcore/src/api/Services/TtvSqlService.cs b/aspnetcore/src/api/Services/TtvSqlService.cs index bea074b0..6d2bda6a 100644 --- a/aspnetcore/src/api/Services/TtvSqlService.cs +++ b/aspnetcore/src/api/Services/TtvSqlService.cs @@ -51,8 +51,8 @@ public string GetFactFieldValuesFKColumnNameFromFieldIdentifier(int fieldIdentif case Constants.FieldIdentifiers.ACTIVITY_PUBLICATION: fk_column_name = "dim_publication_id"; break; - case Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID: - fk_column_name = "dim_orcid_publication_id"; + case Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY: + fk_column_name = "dim_profile_only_publication_id"; break; case Constants.FieldIdentifiers.ACTIVITY_FUNDING_DECISION: fk_column_name = "dim_funding_decision_id"; @@ -125,7 +125,7 @@ public string GetSqlQuery_ProfileData(int userprofileId, bool forElasticsearch = ffv.dim_identifierless_data_id AS 'FactFieldValues_DimIdentifierlessDataId', ffv.dim_education_id AS 'FactFieldValues_DimEducationId', ffv.dim_publication_id AS 'FactFieldValues_DimPublicationId', - ffv.dim_orcid_publication_id AS 'FactFieldValues_DimOrcidPublicationId', + ffv.dim_profile_only_publication_id AS 'FactFieldValues_DimProfileOnlyPublicationId', ffv.dim_research_activity_id AS 'FactFieldValues_DimResearchActivityId', ffv.dim_funding_decision_id AS 'FactFieldValues_DimFundingDecisionId', ffv.dim_research_dataset_id AS 'FactFieldValues_DimResearchDatasetId', @@ -201,10 +201,10 @@ public string GetSqlQuery_ProfileData(int userprofileId, bool forElasticsearch = dim_publication.journal_name AS 'DimPublication_JournalName', dim_publication.conference_name AS 'DimPublication_ConferenceName', dim_publication.parent_publication_name AS 'DimPublication_ParentPublicationName', - dim_orcid_publication.publication_id AS 'DimOrcidPublication_PublicationId', - dim_orcid_publication.publication_name AS 'DimOrcidPublication_PublicationName', - dim_orcid_publication.publication_year AS 'DimOrcidPublication_PublicationYear', - dim_orcid_publication.doi_handle AS 'DimOrcidPublication_Doi', + dim_profile_only_publication.publication_id AS 'DimProfileOnlyPublication_PublicationId', + dim_profile_only_publication.publication_name AS 'DimProfileOnlyPublication_PublicationName', + dim_profile_only_publication.publication_year AS 'DimProfileOnlyPublication_PublicationYear', + dim_profile_only_publication.doi_handle AS 'DimProfileOnlyPublication_Doi', dim_research_activity.name_fi AS 'DimResearchActivity_NameFi', dim_research_activity.name_en AS 'DimResearchActivity_NameEn', dim_research_activity.name_sv AS 'DimResearchActivity_NameSv', @@ -284,7 +284,7 @@ FROM fact_field_values AS ffv LEFT JOIN dim_date AS education_start_date ON dim_education.dim_start_date=education_start_date.id AND education_start_date.id!=-1 LEFT JOIN dim_date AS education_end_date ON dim_education.dim_end_date=education_end_date.id AND education_end_date.id!=-1 JOIN dim_publication ON ffv.dim_publication_id=dim_publication.id - JOIN dim_orcid_publication ON ffv.dim_orcid_publication_id=dim_orcid_publication.id + JOIN dim_profile_only_publication ON ffv.dim_profile_only_publication_id=dim_profile_only_publication.id JOIN dim_research_activity ON ffv.dim_research_activity_id=dim_research_activity.id LEFT JOIN dim_date AS research_activity_start_date ON dim_research_activity.dim_start_date=research_activity_start_date.id AND research_activity_start_date.id!=-1 LEFT JOIN dim_date AS research_activity_end_date ON dim_research_activity.dim_end_date=research_activity_end_date.id AND research_activity_end_date.id!=-1 @@ -318,17 +318,18 @@ LEFT JOIN dim_referencedata AS research_activity_fact_contribution_researcher_na ffv.dim_researcher_description_id != -1 OR ffv.dim_email_addrress_id != -1 OR ffv.dim_telephone_number_id != -1 OR - ffv.dim_referencedata_field_of_science_id != -1 OR ffv.dim_keyword_id != -1 OR ffv.dim_pid_id != -1 OR ffv.dim_affiliation_id != -1 OR ffv.dim_identifierless_data_id != -1 OR ffv.dim_education_id != -1 OR ffv.dim_publication_id != -1 OR - ffv.dim_orcid_publication_id != -1 OR + ffv.dim_profile_only_publication_id != -1 OR ffv.dim_research_activity_id != -1 OR ffv.dim_funding_decision_id != -1 OR - ffv.dim_research_dataset_id != -1 + ffv.dim_research_dataset_id != -1 OR + ffv.dim_referencedata_field_of_science_id != -1 OR + ffv.dim_referencedata_actor_role_id != -1 ) "; } @@ -411,10 +412,10 @@ public string GetSqlQuery_Delete_DimNames(List dimNameIds) return $"DELETE FROM dim_name WHERE id IN ({ConvertListOfIntsToCommaSeparatedString(dimNameIds)})"; } - // Return SQL DELETE statement for dim_orcid_publication - public string GetSqlQuery_Delete_DimOrcidPublications(List dimOrcidPublicationIds) + // Return SQL DELETE statement for dim_profile_only_publication + public string GetSqlQuery_Delete_DimProfileOnlyPublications(List dimProfileOnlyPublicationIds) { - return $"DELETE FROM dim_orcid_publication WHERE id IN ({ConvertListOfIntsToCommaSeparatedString(dimOrcidPublicationIds)})"; + return $"DELETE FROM dim_profile_only_publication WHERE id IN ({ConvertListOfIntsToCommaSeparatedString(dimProfileOnlyPublicationIds)})"; } // Return SQL DELETE statement for dim_pid diff --git a/aspnetcore/src/api/Services/UserProfileService.cs b/aspnetcore/src/api/Services/UserProfileService.cs index 00bbbe64..0d2ee681 100644 --- a/aspnetcore/src/api/Services/UserProfileService.cs +++ b/aspnetcore/src/api/Services/UserProfileService.cs @@ -56,8 +56,15 @@ public UserProfileService(TtvContext ttvContext, _logger = logger; } - // For unit test + // Constructors used in test cases public UserProfileService() { } + public UserProfileService(IUtilityService utilityService) { + _utilityService = utilityService; + } + public UserProfileService(IDataSourceHelperService dataSourceHelperService) + { + _dataSourceHelperService = dataSourceHelperService; + } /* * Get FieldIdentifiers. @@ -78,7 +85,7 @@ public List GetFieldIdentifiers() Constants.FieldIdentifiers.ACTIVITY_AFFILIATION, Constants.FieldIdentifiers.ACTIVITY_EDUCATION, Constants.FieldIdentifiers.ACTIVITY_PUBLICATION, - Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID, + Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY, Constants.FieldIdentifiers.ACTIVITY_FUNDING_DECISION, Constants.FieldIdentifiers.ACTIVITY_RESEARCH_DATASET, Constants.FieldIdentifiers.ACTIVITY_RESEARCH_ACTIVITY @@ -282,12 +289,14 @@ public FactFieldValue GetEmptyFactFieldValue() DimEmailAddrressId = -1, DimResearcherDescriptionId = -1, DimIdentifierlessDataId = -1, - DimOrcidPublicationId = -1, + DimProfileOnlyPublicationId = -1, + DimProfileOnlyResearchActivityId = -1, DimKeywordId = -1, DimAffiliationId = -1, DimResearcherToResearchCommunityId = -1, DimResearchDatasetId = -1, DimReferencedataFieldOfScienceId = -1, + DimReferencedataActorRoleId = -1, Show = false, PrimaryValue = false, SourceId = Constants.SourceIdentifiers.PROFILE_API, @@ -308,17 +317,17 @@ public FactFieldValue GetEmptyFactFieldValueDemo() } /* - * Get empty DimOrcidPublication. + * Get empty DimProfileOnlyPublication. * Must use -1 in required foreign keys. */ - public DimOrcidPublication GetEmptyDimOrcidPublication() + public DimProfileOnlyPublication GetEmptyDimProfileOnlyPublication() { - return new DimOrcidPublication() + return new DimProfileOnlyPublication() { - DimParentOrcidPublicationId = null, - ParentPublicationTypeCode = -1, - PublicationTypeCode = -1, - PublicationTypeCode2 = -1, + DimProfileOnlyPublicationId = null, + ParentTypeClassificationCode = -1, + TypeClassificationCode = -1, + PublicationFormatCode = -1, ArticleTypeCode = -1, TargetAudienceCode = -1, OrcidWorkType = null, @@ -339,7 +348,7 @@ public DimOrcidPublication GetEmptyDimOrcidPublication() ParentPublicationName = null, ParentPublicationEditors = null, LicenseCode = null, - LanguageCode = null, + LanguageCode = -1, OpenAccessCode = null, OriginalPublicationId = null, PeerReviewed = null, @@ -350,7 +359,7 @@ public DimOrcidPublication GetEmptyDimOrcidPublication() SourceDescription = Constants.SourceDescriptions.PROFILE_API, Created = null, Modified = null, - OrcidPersonDataSource = -1, + DimKnownPersonId = -1, DimRegisteredDataSourceId = -1 }; } @@ -377,7 +386,7 @@ public DimPid GetEmptyDimPid() DimResearchDataCatalogId = -1, DimResearchActivityId = -1, DimEventId = -1, - DimOrcidPublicationId = -1, + DimProfileOnlyPublicationId = -1, SourceId = Constants.SourceIdentifiers.PROFILE_API, SourceDescription = Constants.SourceDescriptions.PROFILE_API, Created = _utilityService.GetCurrentDateTime(), @@ -1260,7 +1269,7 @@ public async Task GetProfileDataAsync(int userprofile break; // Publication (ORCID) - case Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_ORCID: + case Constants.FieldIdentifiers.ACTIVITY_PUBLICATION_PROFILE_ONLY: profileDataResponse.activity.publications = _duplicateHandlerService.AddPublicationToProfileEditorData( dataSource: profileEditorSource, @@ -1491,7 +1500,7 @@ await _ttvContext.FactFieldValues.Where(ffv => ffv.DimUserProfileId == userprofi List dimFundingDecisionIds = new(); List dimKeywordIds = new(); List dimNameIds = new(); - List dimOrcidPublicationIds = new(); + List dimProfileOnlyPublicationIds = new(); List dimPidIds = new(); List dimResearchActivityIds = new(); List dimResearchCommunityIds = new(); @@ -1541,7 +1550,7 @@ await connection.ExecuteAsync( if (factFieldValue.DimFundingDecisionId != -1) dimFundingDecisionIds.Add(factFieldValue.DimFundingDecisionId); if (factFieldValue.DimKeywordId != -1) dimKeywordIds.Add(factFieldValue.DimKeywordId); if (factFieldValue.DimNameId != -1) dimNameIds.Add(factFieldValue.DimNameId); - if (factFieldValue.DimOrcidPublicationId != -1) dimOrcidPublicationIds.Add(factFieldValue.DimOrcidPublicationId); + if (factFieldValue.DimProfileOnlyPublicationId != -1) dimProfileOnlyPublicationIds.Add(factFieldValue.DimProfileOnlyPublicationId); if (factFieldValue.DimPidId != -1) dimPidIds.Add(factFieldValue.DimPidId); if (factFieldValue.DimPidIdOrcidPutCode != -1) dimPidIds.Add(factFieldValue.DimPidIdOrcidPutCode); if (factFieldValue.DimResearchActivityId != -1) dimResearchActivityIds.Add(factFieldValue.DimResearchActivityId); @@ -1626,11 +1635,11 @@ await connection.ExecuteAsync( transaction: transaction ); } - // Delete ORCID publications - if (dimOrcidPublicationIds.Count > 0) + // Delete profile only publications + if (dimProfileOnlyPublicationIds.Count > 0) { await connection.ExecuteAsync( - sql: _ttvSqlService.GetSqlQuery_Delete_DimOrcidPublications(dimOrcidPublicationIds), + sql: _ttvSqlService.GetSqlQuery_Delete_DimProfileOnlyPublications(dimProfileOnlyPublicationIds), transaction: transaction ); } diff --git a/aspnetcore/src/api/api.csproj b/aspnetcore/src/api/api.csproj index 5832f23e..7153a3c4 100644 --- a/aspnetcore/src/api/api.csproj +++ b/aspnetcore/src/api/api.csproj @@ -14,6 +14,7 @@ 4 bin\Release\net5.0\api.xml + 1591 @@ -36,8 +37,7 @@ - - + diff --git a/aspnetcore/src/api/appsettings.json b/aspnetcore/src/api/appsettings.json index e6858d50..2ff9d1a6 100644 --- a/aspnetcore/src/api/appsettings.json +++ b/aspnetcore/src/api/appsettings.json @@ -2,7 +2,7 @@ "AllowedHosts": "*", "Serilog": { - "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.OpenSearch" ], + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Http" ], "MinimumLevel": { "Default": "Information", "Override": { @@ -17,11 +17,11 @@ "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" } }, - "OpenSearchSink": { - "Name": "OpenSearch", + "HttpSink": { + "Name": "Http", "Args": { - "autoRegisterTemplate": true, - "indexFormat": "mydata-api-log-{0:yyyy.MM}" + "queueLimitBytes": null, + "httpClient": "Mydatalogging.BasicAuthenticatedHttpClient, api" } } }, @@ -30,4 +30,4 @@ "Application": "CSC.MydataApi" } } -} \ No newline at end of file +}