diff --git a/README.md b/README.md index 41091f1..169b22b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,15 @@ -# Provide +# uoa-repository-manager-service (Provide backend) [...] ## Install and run: - Run **git clone** and then **cd uoa-repository-manager-service**. -- Provide all not-set or redacted configurations, inside the **src/main/resources/application.properties** file. +- Provide all not-set or redacted configurations, inside the **src/main/resources/application.yml** file. - Build the app with: `mvn clean install` - Run the app with: `java -jar ./target/uoa-repository-manager-service.jar` + + +### Notes for Swagger-UI: +- Access it through this url: http://localhost:8480/uoa-repository-manager-service/swagger-ui/index.html +- In order to request data from most endpoints, you have to be a "REGISTERED_USER", otherwise you will get a 403 error code. +- In order to be a registered user, you have to run the [UI-service](https://code-repo.d4science.org/MaDgIK/uoa-repository-manager-ui) , in the same machine, at the same time and login through a browser, using the following url: http://localhost:8480/uoa-repository-manager-service/openid_connect_login diff --git a/pom.xml b/pom.xml index 6e4c908..cfa3754 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.5.4 + 2.7.17 4.0.0 @@ -16,13 +16,14 @@ jar - 2.5.4 + 2.7.17 org.springframework.boot spring-boot-starter-web + ${spring.boot.version} org.springframework.boot @@ -33,47 +34,62 @@ org.springframework.boot spring-boot-starter-log4j2 + ${spring.boot.version} org.springframework.boot spring-boot-starter-data-jdbc + ${spring.boot.version} org.springframework.boot spring-boot-starter-data-jpa + ${spring.boot.version} org.springframework.boot spring-boot-actuator-autoconfigure + ${spring.boot.version} org.springframework.boot spring-boot-starter-data-redis + ${spring.boot.version} org.springframework.boot spring-boot-starter-validation + ${spring.boot.version} org.springframework.boot spring-boot-starter-test + ${spring.boot.version} test + com.h2database h2 + 2.2.224 org.apache.solr solr-solrj - 9.1.1 + 9.4.0 eu.dnetlib.dhp dnet-exporter-api [3.3.3-SNAPSHOT, ) + + + eu.dnetlib + dnet-index-solr-common + + @@ -85,7 +101,6 @@ log4j log4j - javax.servlet javax.servlet-api @@ -118,11 +133,23 @@ + + eu.dnetlib + dnet-openaire-usage-stats-sushilite-r5 + 1.0.0 + system + ${project.basedir}/libs/openaire-usage-stats-sushilite-r5-1.0.0.jar + eu.dnetlib dnet-openaire-usage-stats-sushilite 1.0.0-SNAPSHOT + + eu.dnetlib + dnet-openaire-usage-stats-sushilite-r5 + 1.1.0 + eu.dnetlib.dhp dnet-openaire-broker-common @@ -137,13 +164,13 @@ cglib cglib-nodep - 2.2 + 3.3.0 commons-io commons-io - 2.4 + 2.15.0 @@ -151,63 +178,74 @@ oai4j [0.6b1,) + + xalan xalan - 2.7.2 + 2.7.3 + - com.sun.jersey + org.glassfish.jersey.core jersey-client - 1.19.3 + 2.41 + + org.aksw.gson gson-utils-core - 1.0.0 + 1.0.1 + org.json json - 20080701 + 20231013 com.sun.mail javax.mail - 1.6.0 + 1.6.2 - io.springfox - springfox-swagger2 - 2.7.0 + org.springdoc + springdoc-openapi-webmvc-core + 1.7.0 - io.springfox - springfox-swagger-ui - 2.7.0 + org.springdoc + springdoc-openapi-ui + 1.7.0 + + + org.springdoc + springdoc-openapi-security + 1.7.0 - + - postgresql + org.postgresql postgresql - 9.1-901.jdbc3 + 42.6.0 commons-fileupload commons-fileupload - 1.4 + 1.5 org.mitre openid-connect-client - 1.3.0 + 1.3.4 org.slf4j @@ -218,36 +256,40 @@ org.springframework.session spring-session-data-redis + 2.7.4 redis.clients jedis - ${jedis.version} + ${jedis.version} + org.apache.commons commons-pool2 + 2.12.0 + com.google.code.gson gson - 2.6.2 + 2.10.1 com.thetransactioncompany cors-filter - 2.5 + 3.0 javax.xml.ws jaxws-api - 2.3.0 + 2.3.1 @@ -258,23 +300,23 @@ javax.xml.bind jaxb-api - 2.3.0 + 2.3.1 com.sun.xml.bind jaxb-impl - 2.3.0 + 2.3.9 com.sun.xml.bind jaxb-core - 2.3.0 + 2.3.0.1 javax.activation activation - 1.1-rev-1 + 1.1.1 @@ -297,7 +339,7 @@ org.springframework.session spring-session-bom - 2021.0.2 + 2021.2.3 pom import @@ -311,7 +353,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.11.0 1.8 1.8 @@ -321,22 +363,23 @@ org.apache.maven.plugins maven-war-plugin - 2.6 + 3.4.0 false - - --> + + --> org.springframework.boot spring-boot-maven-plugin + ${spring.boot.version} cz.habarta.typescript-generator typescript-generator-maven-plugin - 2.16.538 + 2.37.1128 java to typeScript @@ -421,6 +464,10 @@ false + diff --git a/src/main/java/eu/dnetlib/repo/manager/Application.java b/src/main/java/eu/dnetlib/repo/manager/Application.java index 0eeb9c8..1b74a64 100644 --- a/src/main/java/eu/dnetlib/repo/manager/Application.java +++ b/src/main/java/eu/dnetlib/repo/manager/Application.java @@ -1,12 +1,16 @@ -package eu.dnetlib.repo.manager; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} +package eu.dnetlib.repo.manager; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication +@EnableJpaRepositories +@EnableScheduling +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/components/ScheduledTasks.java b/src/main/java/eu/dnetlib/repo/manager/components/ScheduledTasks.java new file mode 100644 index 0000000..c4688c1 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/components/ScheduledTasks.java @@ -0,0 +1,20 @@ +package eu.dnetlib.repo.manager.components; + + +import eu.dnetlib.repo.manager.service.PendingUserRoleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class ScheduledTasks { + + @Autowired + PendingUserRoleService pendingUserRoleService; + + @Scheduled(fixedRate = 3_600_000) + public void assignPendingRoles() { + pendingUserRoleService.assignRoles(); + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java b/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java index 0a02ce5..407d6b4 100644 --- a/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java +++ b/src/main/java/eu/dnetlib/repo/manager/config/AaiSecurityConfiguration.java @@ -63,12 +63,15 @@ public class AaiSecurityConfiguration extends WebSecurityConfigurerAdapter { .csrf().disable() .authorizeRequests() .regexMatchers("/actuator/.*").permitAll() + .regexMatchers("/repositories/.*/metrics/?.*").permitAll() .regexMatchers("/metrics").permitAll() + .antMatchers("/api-docs/**","/swagger-ui/**").permitAll() .anyRequest().authenticated() .and() .logout().logoutUrl("/openid_logout") + .clearAuthentication(true) .invalidateHttpSession(true) - .deleteCookies("openAIRESession") + .deleteCookies() .logoutSuccessUrl(logoutSuccessUrl) .and() .addFilterBefore(openIdConnectAuthenticationFilter(), AbstractPreAuthenticatedProcessingFilter.class) diff --git a/src/main/java/eu/dnetlib/repo/manager/config/JPAConfig.java b/src/main/java/eu/dnetlib/repo/manager/config/JPAConfig.java new file mode 100644 index 0000000..2036ee2 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/config/JPAConfig.java @@ -0,0 +1,17 @@ +package eu.dnetlib.repo.manager.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +@Configuration +public class JPAConfig { + + @Bean + public PlatformTransactionManager transactionManager() { + return new JpaTransactionManager(); + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/config/OpenAPIConfiguration.java b/src/main/java/eu/dnetlib/repo/manager/config/OpenAPIConfiguration.java new file mode 100644 index 0000000..809b286 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/config/OpenAPIConfiguration.java @@ -0,0 +1,23 @@ +package eu.dnetlib.repo.manager.config; + + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.info.Contact; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.info.License; + +@OpenAPIDefinition( + info = @Info( + title = "Repository Manager Dashboard API Documentation", + description = "Repository Manager Dashboard API Documentation", + version = "1.0", + termsOfService = "urn:tos", + license = @License( + name = "Apache 2.0", + url = "https://www.apache.org/licenses/LICENSE-2.0.html" + ), + contact = @Contact(name = "", url = "", email = "") + ) +) +public class OpenAPIConfiguration { +} diff --git a/src/main/java/eu/dnetlib/repo/manager/config/SwaggerConfig.java b/src/main/java/eu/dnetlib/repo/manager/config/SwaggerConfig.java deleted file mode 100644 index 9e4893b..0000000 --- a/src/main/java/eu/dnetlib/repo/manager/config/SwaggerConfig.java +++ /dev/null @@ -1,47 +0,0 @@ -package eu.dnetlib.repo.manager.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.service.VendorExtension; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.ArrayList; - - -/** - * Created by panagiotis on 16/11/2017. - */ -@Configuration -@EnableSwagger2 -@EnableWebMvc -public class SwaggerConfig { - - @Bean - public Docket productApi() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build() - .pathMapping("/") - .apiInfo(getApiInfo()); - } - - private ApiInfo getApiInfo() { - return new ApiInfo("Repository Manager Dashboard API Documentation", - "Repository Manager Dashboard API Documentation", - "1.0", - "urn:tos", - new Contact("", "", ""), - "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", - new ArrayList()); - } - -} diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java index 187da9c..f96af01 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/BrokerController.java @@ -4,8 +4,8 @@ import eu.dnetlib.repo.manager.domain.Term; import eu.dnetlib.repo.manager.domain.broker.*; import eu.dnetlib.repo.manager.exception.BrokerException; import eu.dnetlib.repo.manager.service.BrokerServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.json.JSONException; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.beans.factory.annotation.Autowired; @@ -21,7 +21,7 @@ import java.util.Map; @RestController @RequestMapping(value = "/broker") -@Api(description = "Broker API", tags = {"broker"}) +@Tag(name="broker", description="Broker API") public class BrokerController{ @Autowired @@ -33,9 +33,9 @@ public class BrokerController{ @PreAuthorize("hasAuthority('REGISTERED_USER')") public DatasourcesBroker getDatasourcesOfUser( @RequestParam("includeShared") - @ApiParam(value = "Include shared datasources", required = true , defaultValue = "false") String includeShared, + @Parameter(description = "Include shared datasources (default = false)", required = true) String includeShared, @RequestParam("includeByOthers") - @ApiParam(value = "Include datasources of other", required = true,defaultValue = "false") String includeByOthers) throws JSONException { + @Parameter(description = "Include datasources of other (default = false)", required = true) String includeByOthers) throws JSONException { return brokerService.getDatasourcesOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), includeShared, includeByOthers); } diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java index 3fd6650..5a1d7fb 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/DashboardController.java @@ -8,7 +8,7 @@ import eu.dnetlib.repo.manager.domain.UsageSummary; import eu.dnetlib.repo.manager.exception.BrokerException; import eu.dnetlib.repo.manager.exception.RepositoryServiceException; import eu.dnetlib.repo.manager.service.*; -import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.tags.Tag; import org.json.JSONException; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.beans.factory.annotation.Autowired; @@ -21,7 +21,7 @@ import java.util.List; @RestController @RequestMapping(value = "/dashboard") -@Api(description = "Dashboard API", tags = {"dashboard"}) +@Tag(name="dashboard", description = "Dashboard API") public class DashboardController { @Autowired diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java index 69b04db..db24ca6 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/MonitorController.java @@ -4,8 +4,8 @@ import eu.dnetlib.api.functionality.ValidatorServiceException; import eu.dnetlib.domain.functionality.validator.StoredJob; import eu.dnetlib.repo.manager.domain.JobsOfUser; import eu.dnetlib.repo.manager.service.MonitorServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.json.JSONException; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.slf4j.Logger; @@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; @RestController @RequestMapping(value = "/monitor") -@Api(description = "Monitor API", tags = {"monitor"}) +@Tag(name="monitor", description="Monitor API") public class MonitorController { private static final Logger logger = LoggerFactory.getLogger(MonitorController.class); @@ -31,13 +31,13 @@ public class MonitorController { @ResponseBody @PreAuthorize("hasAuthority('REGISTERED_USER')") public JobsOfUser getJobsOfUser(@RequestParam(value = "jobType", required = false) - @ApiParam(value = "Equals to filter job type on validation history page") String jobType, - @RequestParam("offset") @ApiParam(value = "Page number", required = true) String offset, - @RequestParam(value = "limit", required = false,defaultValue = "10") @ApiParam(value = "Null value") String limit, - @RequestParam(value = "dateFrom", required = false) @ApiParam(value = "Null value") String dateFrom, - @RequestParam(value = "dateTo", required = false) @ApiParam(value = "Null value") String dateTo, - @RequestParam("validationStatus") @ApiParam(value = "Equals to filter validation jobs", required = false) String validationStatus, - @RequestParam("includeJobsTotal") @ApiParam(value = "Always true", required = true) String includeJobsTotal) throws JSONException, ValidatorServiceException { + @Parameter(description = "Equals to filter job type on validation history page") String jobType, + @RequestParam("offset") @Parameter(name = "Page number", required = true) String offset, + @RequestParam(value = "limit", required = false,defaultValue = "10") @Parameter(description = "Null value") String limit, + @RequestParam(value = "dateFrom", required = false) @Parameter(description = "Null value") String dateFrom, + @RequestParam(value = "dateTo", required = false) @Parameter(description = "Null value") String dateTo, + @RequestParam("validationStatus") @Parameter(description = "Equals to filter validation jobs", required = false) String validationStatus, + @RequestParam("includeJobsTotal") @Parameter(description = "Always true", required = true) String includeJobsTotal) throws JSONException, ValidatorServiceException { return monitorService.getJobsOfUser(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobType, offset, limit, dateFrom, dateTo, validationStatus, includeJobsTotal); } diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java index 709808d..7bb96e9 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/PiWikController.java @@ -6,9 +6,9 @@ import eu.dnetlib.repo.manager.domain.OrderByType; import eu.dnetlib.repo.manager.domain.Paging; import eu.dnetlib.repo.manager.exception.RepositoryServiceException; import eu.dnetlib.repo.manager.service.PiWikServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,7 +31,7 @@ import java.util.List; @RestController @RequestMapping(value = "/piwik") -@Api(description = "Piwik API", tags = {"piwik"}) +@Tag(name="piwik", description = "Piwik API") public class PiWikController { private static final Logger logger = LoggerFactory.getLogger(PiWikController.class); @@ -63,17 +63,17 @@ public class PiWikController { } @RequestMapping(value = "/getPiwikSitesForRepos" , method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) - @ApiImplicitParams({ - @ApiImplicitParam(name = "from", dataType = "number", paramType = "query"), - @ApiImplicitParam(name = "quantity", dataType = "number", paramType = "query"), - @ApiImplicitParam(name = "order", dataType = "eu.dnetlib.repo.manager.domain.OrderByType", paramType = "query"), - @ApiImplicitParam(name = "orderField", dataType = "eu.dnetlib.repo.manager.domain.OrderByField", paramType = "query"), - @ApiImplicitParam(name = "searchField", dataType = "string", paramType = "query"), + @Parameters({ + @Parameter(name = "from", description = "number"), + @Parameter(name = "quantity", description = "number"), + @Parameter(name = "order", description = "eu.dnetlib.repo.manager.domain.OrderByType"), + @Parameter(name = "orderField", description = "eu.dnetlib.repo.manager.domain.OrderByField"), + @Parameter(name = "searchField", description = "string") }) public Paging getPiwikSitesForRepos( - @RequestParam(value = "from",required=false,defaultValue = "0") int from, - @RequestParam(value = "quantity",required=false,defaultValue = "100") int quantity, - @RequestParam(value = "order",required=false,defaultValue = "DSC") OrderByType orderType, + @RequestParam(value = "from", required=false, defaultValue = "0") int from, + @RequestParam(value = "quantity", required=false, defaultValue = "100") int quantity, + @RequestParam(value = "order", required=false, defaultValue = "DSC") OrderByType orderType, @RequestParam(value = "orderField", required = false, defaultValue = "REPOSITORY_NAME") OrderByField orderField, @RequestParam(value = "searchField", required = false, defaultValue = "") String searchField @@ -87,12 +87,12 @@ public class PiWikController { return results; } - @ApiImplicitParams({ - @ApiImplicitParam(name = "from", dataType = "number", paramType = "query"), - @ApiImplicitParam(name = "quantity", dataType = "number", paramType = "query"), - @ApiImplicitParam(name = "order", dataType = "eu.dnetlib.repo.manager.domain.OrderByType", paramType = "query"), - @ApiImplicitParam(name = "searchField", dataType = "eu.dnetlib.repo.manager.domain.OrderByField", paramType = "query"), - @ApiImplicitParam(name = "orderField", dataType = "string", paramType = "query"), + @Parameters({ + @Parameter(name = "from", description = "number"), + @Parameter(name = "quantity", description = "number"), + @Parameter(name = "order", description = "eu.dnetlib.repo.manager.domain.OrderByType"), + @Parameter(name = "searchField", description = "eu.dnetlib.repo.manager.domain.OrderByField"), + @Parameter(name = "orderField", description = "string") }) @RequestMapping(value = "/getPiwikSitesForRepos/csv" , method = RequestMethod.GET,produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @ResponseBody diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java index 7712547..d36a915 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/RepositoryController.java @@ -1,5 +1,6 @@ package eu.dnetlib.repo.manager.controllers; +import eu.dnetlib.domain.data.PiwikInfo; import eu.dnetlib.enabling.datasources.common.AggregationInfo; import eu.dnetlib.repo.manager.domain.*; import eu.dnetlib.repo.manager.domain.dto.RepositoryTerms; @@ -7,10 +8,12 @@ import eu.dnetlib.repo.manager.domain.dto.User; import eu.dnetlib.repo.manager.exception.RepositoryServiceException; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; import eu.dnetlib.repo.manager.service.AggregationService; +import eu.dnetlib.repo.manager.service.PiWikService; +import eu.dnetlib.repo.manager.service.PiWikServiceImpl; import eu.dnetlib.repo.manager.service.RepositoryService; import eu.dnetlib.repo.manager.service.security.AuthorizationService; import eu.dnetlib.repo.manager.utils.JsonUtils; -import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.tags.Tag; import org.json.JSONException; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.slf4j.Logger; @@ -32,7 +35,7 @@ import java.util.Map; @RestController @RequestMapping(value = "/repositories") -@Api(description = "Repository API", tags = {"repositories"}) +@Tag(name="repositories", description="Repository API") public class RepositoryController { private static final Logger logger = LoggerFactory.getLogger(RepositoryController.class); @@ -43,12 +46,17 @@ public class RepositoryController { private final AuthorizationService authorizationService; + private final PiWikService piWikService; + @Autowired RepositoryController(RepositoryService repositoryService, - AggregationService aggregationService, AuthorizationService authorizationService) { + AggregationService aggregationService, + AuthorizationService authorizationService, + PiWikService piWikService) { this.repositoryService = repositoryService; this.aggregationService = aggregationService; this.authorizationService = authorizationService; + this.piWikService = piWikService; } @RequestMapping(value = "/countries", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @@ -295,4 +303,26 @@ public class RepositoryController { authorizationService.removeAdmin(id, email); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Returns whether the Piwik Site of a repository is enabled and validated. + */ + @RequestMapping(value = "{repositoryId}/metrics/valid", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + public boolean getMetricsEnabledAndValidated(@PathVariable("repositoryId") String repositoryId) { + PiwikInfo info = piWikService.getPiwikSiteForRepo(repositoryId); + return info != null && info.isValidated(); + } + + /** + * Returns repository Metrics. + */ + @RequestMapping(value = "{repositoryId}/metrics", method = RequestMethod.GET, + produces = MediaType.APPLICATION_JSON_VALUE) + public MetricsInfo getMetricsInfo(@PathVariable("repositoryId") String id) throws RepositoryServiceException { + return repositoryService.getMetricsInfoForRepository(id); + } + } diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java index 1cfd6a2..916b066 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/StatsController.java @@ -1,7 +1,7 @@ package eu.dnetlib.repo.manager.controllers; import eu.dnetlib.repo.manager.service.StatsServiceImpl; -import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; @@ -13,7 +13,7 @@ import java.util.Map; @RestController @RequestMapping(value = "/stats") -@Api(description = "Stats API", tags = {"statistics"}) +@Tag(name="statistics", description = "Stats API") public class StatsController { @Autowired diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java index 7d7aa4e..5d6d49d 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteController.java @@ -1,8 +1,8 @@ package eu.dnetlib.repo.manager.controllers; -import eu.dnetlib.repo.manager.service.SushiliteServiceImpl; +import eu.dnetlib.repo.manager.service.sushilite.SushiliteServiceImpl; import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper; -import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; @@ -10,10 +10,9 @@ import org.springframework.web.bind.annotation.*; @RestController @RequestMapping(value = "/sushilite") -@Api(description = "Sushi-Lite API", tags = {"sushilite"}) +@Tag(name="sushilite", description = "Sushi-Lite API") public class SushiliteController { - @Autowired private SushiliteServiceImpl sushiliteService; diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteR5Controller.java b/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteR5Controller.java new file mode 100644 index 0000000..4ba447e --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/SushiliteR5Controller.java @@ -0,0 +1,52 @@ +package eu.dnetlib.repo.manager.controllers; + +import eu.dnetlib.repo.manager.service.sushilite.SushiliteR5ServiceImpl; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.json.JSONException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +@RestController +@RequestMapping(value = "/sushiliteR5") +@Tag(name="sushiliteR5", description = "Sushi-Lite R5 API") +public class SushiliteR5Controller { + + + private static final Logger logger = LoggerFactory.getLogger(SushiliteR5Controller.class); + + + @Autowired + private SushiliteR5ServiceImpl sushiliteR5Service; + + @RequestMapping(value = "/getReportResults", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + @PreAuthorize("hasAuthority('REGISTERED_USER')") + public ResponseEntity getReportResults(@RequestParam(value = "Report") String report, + @RequestParam(value = "Release", required=false, defaultValue="5") String release, + @RequestParam(value = "RequestorID",required=false, defaultValue="anonymous") String requestorID, + @RequestParam(value = "BeginDate",required=false, defaultValue="") String beginDate, + @RequestParam(value = "EndDate",required=false, defaultValue="") String endDate, + @RequestParam(value = "RepositoryIdentifier", required=false, defaultValue="") String repositoryIdentifier, + @RequestParam(value = "DatasetIdentifier", required=false, defaultValue="") String datasetIdentifier, + @RequestParam(value = "ItemIdentifier",required=false, defaultValue="") String itemIdentifier, + @RequestParam(value = "MetricType",required=false) List metricTypes, + @RequestParam(value = "DataType",required=false, defaultValue="") String dataType, + @RequestParam(value = "Granularity", required = false, defaultValue ="Monthly") String granularity, + @RequestParam(value = "Pretty",required=false, defaultValue="") String pretty) { + try { + return sushiliteR5Service.getReportResults(report, release, requestorID, beginDate, endDate, repositoryIdentifier, datasetIdentifier, itemIdentifier, metricTypes, dataType, granularity, pretty); + } catch (JSONException je) { + logger.error("", je); + return ResponseEntity.internalServerError().build(); + } + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java index 08e2119..f93de82 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/UserController.java @@ -1,7 +1,7 @@ package eu.dnetlib.repo.manager.controllers; import eu.dnetlib.repo.manager.service.UserServiceImpl; -import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "/user") -@Api(description = "User API", tags = {"user"}) +@Tag(name="user", description = "User API") public class UserController { @Autowired diff --git a/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java b/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java index f94d860..df23d7f 100644 --- a/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java +++ b/src/main/java/eu/dnetlib/repo/manager/controllers/ValidatorController.java @@ -9,8 +9,8 @@ import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; import eu.dnetlib.repo.manager.exception.ValidationServiceException; import eu.dnetlib.repo.manager.service.EmailUtils; import eu.dnetlib.repo.manager.service.ValidatorServiceImpl; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.json.JSONException; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.springframework.beans.factory.annotation.Autowired; @@ -25,7 +25,7 @@ import java.util.List; @RestController @RequestMapping(value = "/validator") -@Api(description = "Validator API", tags = {"validator"}) +@Tag(name="validator", description = "Validator API") public class ValidatorController { @Autowired @@ -80,12 +80,12 @@ public class ValidatorController { @ResponseBody @PreAuthorize("hasAuthority('REGISTERED_USER')") public List getStoredJobsNew(@RequestParam(value = "jobType", required = false) - @ApiParam(value = "Equals to filter job type on validation history page") String jobType, - @RequestParam("offset") @ApiParam(value = "Page number", required = true) String offset, - @RequestParam(value = "limit", required = false,defaultValue = "10") @ApiParam(value = "Null value") String limit, - @RequestParam(value = "dateFrom", required = false) @ApiParam(value = "Null value") String dateFrom, - @RequestParam(value = "dateTo", required = false) @ApiParam(value = "Null value") String dateTo, - @RequestParam("validationStatus") @ApiParam(value = "Equals to filter validation jobs", required = true) String validationStatus + @Parameter(description = "Equals to filter job type on validation history page") String jobType, + @RequestParam("offset") @Parameter(description = "Page number", required = true) String offset, + @RequestParam(value = "limit", required = false,defaultValue = "10") @Parameter(description = "Null value") String limit, + @RequestParam(value = "dateFrom", required = false) @Parameter(description = "Null value") String dateFrom, + @RequestParam(value = "dateTo", required = false) @Parameter(description = "Null value") String dateTo, + @RequestParam("validationStatus") @Parameter(description = "Equals to filter validation jobs", required = true) String validationStatus ) throws ValidatorServiceException { return validatorService.getStoredJobsNew(((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail(), jobType, offset, limit, dateFrom, dateTo, validationStatus); } diff --git a/src/main/java/eu/dnetlib/repo/manager/domain/PendingUserRole.java b/src/main/java/eu/dnetlib/repo/manager/domain/PendingUserRole.java new file mode 100644 index 0000000..65dd507 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/domain/PendingUserRole.java @@ -0,0 +1,53 @@ +package eu.dnetlib.repo.manager.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class PendingUserRole { + @Id + long id; + int coPersonId; + int couId; + + public PendingUserRole() { + // no-arg constructor + } + + public PendingUserRole(int coPersonId, int couId) { + this.coPersonId = coPersonId; + this.couId = couId; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public int getCoPersonId() { + return coPersonId; + } + + public void setCoPersonId(int coPersonId) { + this.coPersonId = coPersonId; + } + + public int getCouId() { + return couId; + } + + public void setCouId(int couId) { + this.couId = couId; + } + + @Override + public String toString() { + return "PendingUserRole{" + + "coPersonId=" + coPersonId + + ", couId=" + couId + + '}'; + } +} diff --git a/src/main/java/eu/dnetlib/repo/manager/repository/PendingUserRoleRepository.java b/src/main/java/eu/dnetlib/repo/manager/repository/PendingUserRoleRepository.java new file mode 100644 index 0000000..6f1247a --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/repository/PendingUserRoleRepository.java @@ -0,0 +1,9 @@ +package eu.dnetlib.repo.manager.repository; + +import eu.dnetlib.repo.manager.domain.PendingUserRole; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PendingUserRoleRepository extends CrudRepository { +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/InterfaceComplianceService.java b/src/main/java/eu/dnetlib/repo/manager/service/InterfaceComplianceService.java index ddbeaa3..dfa6b91 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/InterfaceComplianceService.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/InterfaceComplianceService.java @@ -41,19 +41,26 @@ public class InterfaceComplianceService { Set requests = getOutdated(); // TODO - In case we want to send the emails, uncomment the following code. - /*for (InterfaceComplianceRequest request : requests) { + /*for ( InterfaceComplianceRequest request : requests ) + { + String repoId = request.getRepositoryId(); + String interfaceId = request.getInterfaceId(); try { - Map repositoryInterfaceMap = repositoryService.getRepositoryInterface(request.getRepositoryId()) + Map repositoryInterfaceMap = repositoryService.getRepositoryInterface(repoId) .stream() .collect(Collectors.toMap(ApiDetails::getId, i -> i)); - Repository repo = repositoryService.getRepositoryById(request.getRepositoryId()); - RepositoryInterface iFace = repositoryInterfaceMap.get(request.getInterfaceId()); - List repositoryAdmins = authorizationService.getAdminsOfRepo(request.getRepositoryId()); + RepositoryInterface iFace = repositoryInterfaceMap.get(interfaceId); + if ( iFace == null ) { + logger.error("The repository-interface \"" + interfaceId + "\" does not exist! | the request had the \"repoId\": \"" + repoId + "\""); + continue; + } + Repository repo = repositoryService.getRepositoryById(repoId); + List repositoryAdmins = authorizationService.getAdminsOfRepo(repoId); emailUtils.sendUserUpdateInterfaceComplianceFailure(repositoryAdmins.stream().map(User::getEmail).collect(Collectors.toList()), repo, iFace, request); emailUtils.sendAdminUpdateInterfaceComplianceFailure(repo, iFace, request); } catch (ResourceNotFoundException e) { - logger.error("Error", e); - } + logger.error("Error for request with \"repoId\": \"" + repoId + "\" and \"interfaceId\": \"" + interfaceId + "\"", e); + } // Continue to the next request. }*/ repository.deleteAll(requests); diff --git a/src/main/java/eu/dnetlib/repo/manager/service/PendingUserRoleService.java b/src/main/java/eu/dnetlib/repo/manager/service/PendingUserRoleService.java new file mode 100644 index 0000000..cf7a99a --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/PendingUserRoleService.java @@ -0,0 +1,36 @@ +package eu.dnetlib.repo.manager.service; + +import eu.dnetlib.repo.manager.domain.PendingUserRole; +import eu.dnetlib.repo.manager.repository.PendingUserRoleRepository; +import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class PendingUserRoleService { + + private static final Logger logger = LoggerFactory.getLogger(PendingUserRoleService.class); + private final PendingUserRoleRepository pendingUserRoleRepository; + private final AaiRegistryService aaiRegistryService; + + public PendingUserRoleService(PendingUserRoleRepository pendingUserRoleRepository, + AaiRegistryService aaiRegistryService) { + this.pendingUserRoleRepository = pendingUserRoleRepository; + this.aaiRegistryService = aaiRegistryService; + } + + public void assignRoles() { + Iterable roles = pendingUserRoleRepository.findAll(); + for (PendingUserRole role : roles) { + logger.debug("Attempt to assign role: {}", role); + try { + aaiRegistryService.assignMemberRole(role.getCoPersonId(), role.getCouId()); + pendingUserRoleRepository.deleteById(role.getId()); + } catch (Exception e) { + logger.warn("Could not assign role to user. Pending Role: {}\n", role, e); + } + } + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java index 369f21d..cff079b 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryService.java @@ -4,7 +4,6 @@ import eu.dnetlib.api.functionality.ValidatorServiceException; import eu.dnetlib.repo.manager.domain.*; import eu.dnetlib.repo.manager.exception.RepositoryServiceException; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; -import org.json.JSONException; import org.springframework.security.core.Authentication; import java.util.List; diff --git a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java index e05c9cc..77e1068 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/RepositoryServiceImpl.java @@ -28,6 +28,7 @@ import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -38,6 +39,7 @@ import javax.annotation.PostConstruct; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; @Service("repositoryService") public class RepositoryServiceImpl implements RepositoryService { @@ -284,14 +286,14 @@ public class RepositoryServiceImpl implements RepositoryService { public List getRepositoriesOfUser(String page, String size) { logger.debug("Retrieving repositories of authenticated user : {}", ((OIDCAuthenticationToken) SecurityContextHolder.getContext().getAuthentication()).getUserInfo().getEmail()); - Collection repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles()); + Collection repoIds = roleMappingService.getRepositoryIds(authorizationService.getUserRoles()); return getRepositories(new ArrayList<>(repoIds)); } @Override public List getRepositoriesOfUser(String userEmail, String page, String size) { logger.debug("Retrieving repositories of authenticated user : {}", userEmail); - Collection repoIds = roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRolesByEmail(userEmail)); + Collection repoIds = roleMappingService.getRepositoryIds(authorizationService.getUserRolesByEmail(userEmail)); return getRepositories(new ArrayList<>(repoIds)); } @@ -304,12 +306,7 @@ public class RepositoryServiceImpl implements RepositoryService { public List getRepositoriesSnippetsOfUser(String userEmail, String page, String size) { int from = Integer.parseInt(page) * Integer.parseInt(size); int to = from + Integer.parseInt(size); - List repoIds = new ArrayList<>(); - if (userEmail != null && !"".equals(userEmail)) { - repoIds.addAll(roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRolesByEmail(userEmail))); - } else { - repoIds.addAll(roleMappingService.getRepoIdsByRoleIds(authorizationService.getUserRoles())); - } + List repoIds = getRepoIdsOfUser(userEmail); if (repoIds.size() < from) { return Collections.emptyList(); @@ -534,8 +531,8 @@ public class RepositoryServiceImpl implements RepositoryService { emailUtils.sendUserRegisterInterfaceEmail(repo, comment, repositoryInterface, desiredCompatibilityLevel, authentication); String prevCompatibilityLevel = repositoryInterface.getCompatibility(); - if ( (desiredCompatibilityLevel != null) - && ((prevCompatibilityLevel == null) || ! prevCompatibilityLevel.equals(desiredCompatibilityLevel))) { + if ((desiredCompatibilityLevel != null) + && ((prevCompatibilityLevel == null) || !prevCompatibilityLevel.equals(desiredCompatibilityLevel))) { InterfaceComplianceRequest request = new InterfaceComplianceRequest(repoId, repositoryInterface.getId(), desiredCompatibilityLevel); interfaceComplianceService.create(request); } @@ -955,10 +952,27 @@ public class RepositoryServiceImpl implements RepositoryService { return repositories; } + private List getRepoIdsOfUser(String userEmail) { + List repoIds; + if (userEmail != null && !"".equals(userEmail)) { + repoIds = new ArrayList<>(roleMappingService.getRepositoryIds(authorizationService.getUserRolesByEmail(userEmail))); + } else { + Collection authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities(); + repoIds = authorities + .stream() + .map(a -> roleMappingService.authorityToRepositoryId((GrantedAuthority) a)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + return repoIds; + } + + @Deprecated private String getRepositoryType(String typology) { return invertedDataSourceClass.get(typology); } + @Deprecated private List getRoleIdsFromUserRoles(String userEmail) { List coPersonId = registryCalls.getCoPersonIdsByEmail(userEmail); JsonArray roles; diff --git a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java index c7d4743..224267d 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/RegistryCalls.java @@ -15,6 +15,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -55,7 +56,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public List getUserIdentifiersByCoPersonId(Integer coPersonId) { + public List getUserIdentifiersByCoPersonId(Integer coPersonId) throws RestClientException { List ids = new ArrayList<>(); Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); @@ -86,7 +87,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public List getCoPersonIdsByEmail(String email) { + public List getCoPersonIdsByEmail(String email) throws RestClientException { List coPersonIds = new ArrayList<>(); Map params = new HashMap<>(); params.put("mail", email); @@ -113,7 +114,7 @@ public class RegistryCalls implements AaiRegistryService { } } - public Integer getCoPersonIdByIdentifier(String sub) { + public Integer getCoPersonIdByIdentifier(String sub) throws RestClientException { Map params = new HashMap<>(); params.put("search.identifier", sub); params.put("coid", coid); @@ -122,7 +123,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getCous(String name) { + public JsonArray getCous(String name) throws RestClientException { Map params = new HashMap<>(); if (name != null) { try { @@ -163,8 +164,9 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getRoles(Integer coPersonId) { + public JsonArray getRoles(Integer coPersonId) throws RestClientException { Map params = new HashMap<>(); + params.put("coid", coid); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("co_person_roles.json", params); return (response != null) ? response.getAsJsonObject().get("CoPersonRoles").getAsJsonArray() : new JsonArray(); @@ -203,7 +205,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getUserGroups(Integer coPersonId) { + public JsonArray getUserGroups(Integer coPersonId) throws RestClientException { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("co_groups.json", params); @@ -211,7 +213,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonObject getUserAdminGroup(Integer coPersonId, Integer couId) { + public JsonObject getUserAdminGroup(Integer coPersonId, Integer couId) throws RestClientException { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("co_groups.json", params); @@ -228,7 +230,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getCouGroups(Integer couId) { + public JsonArray getCouGroups(Integer couId) throws RestClientException { Map params = new HashMap<>(); params.put("couid", couId.toString()); JsonElement response = httpUtils.get("co_groups.json", params); @@ -247,7 +249,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getGroupMembers(Integer coGroupId) { + public JsonArray getGroupMembers(Integer coGroupId) throws RestClientException { Map params = new HashMap<>(); params.put("cogroupid", coGroupId.toString()); JsonElement response = httpUtils.get("co_group_members.json", params); @@ -256,7 +258,7 @@ public class RegistryCalls implements AaiRegistryService { @Override - public JsonArray getUserEmailByCouId(Integer couId, boolean admin) { + public JsonArray getUserEmailByCouId(Integer couId, boolean admin) throws RestClientException { Map params = new HashMap<>(); if (couId == null) { throw new IllegalArgumentException("Provided 'couId' is null"); @@ -287,7 +289,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getUsersByCouId(Integer couId) { + public JsonArray getUsersByCouId(Integer couId) throws RestClientException { Map params = new HashMap<>(); params.put("couid", couId.toString()); JsonElement response = httpUtils.get("co_person_roles.json", params); @@ -320,7 +322,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getUserNamesByCouId(Integer couId, boolean admin) { + public JsonArray getUserNamesByCouId(Integer couId, boolean admin) throws RestClientException { Map params = new HashMap<>(); params.put("couid", couId.toString()); if (admin) { @@ -340,7 +342,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public JsonArray getUserIdByCouId(Integer couId, boolean admin) { + public JsonArray getUserIdByCouId(Integer couId, boolean admin) throws RestClientException { Map params = new HashMap<>(); params.put("couid", couId.toString()); if (admin) { @@ -360,26 +362,26 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public void assignMemberRole(Integer coPersonId, Integer couId) { + public void assignMemberRole(Integer coPersonId, Integer couId) throws RestClientException { httpUtils.post("co_person_roles.json", jsonUtils.coPersonRoles(coPersonId, couId, "Active")); } @Override - public void removeMemberRole(Integer coPersonId, Integer couId, Integer id) { + public void removeMemberRole(Integer coPersonId, Integer couId, Integer id) throws RestClientException { if (id != null) { httpUtils.put("co_person_roles/" + id + ".json", jsonUtils.coPersonRoles(coPersonId, couId, "Deleted")); } } @Override - public Integer createRole(Role role) { + public Integer createRole(Role role) throws RestClientException { JsonElement element = httpUtils.post("cous.json", jsonUtils.createNewCou(role)); return element.getAsJsonObject().get("Id").getAsInt(); } @Override - public String getUserEmail(Integer coPersonId) { + public String getUserEmail(Integer coPersonId) throws RestClientException { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("email_addresses.json", params); @@ -388,7 +390,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public String getUserNames(Integer coPersonId) { + public String getUserNames(Integer coPersonId) throws RestClientException { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("names.json", params); @@ -401,7 +403,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public String getUserId(Integer coPersonId) { + public String getUserId(Integer coPersonId) throws RestClientException { Map params = new HashMap<>(); params.put("copersonid", coPersonId.toString()); JsonElement response = httpUtils.get("identifiers.json", params); @@ -410,7 +412,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public void assignAdminRole(Integer coPersonId, Integer couId) { + public void assignAdminRole(Integer coPersonId, Integer couId) throws RestClientException { JsonObject group = getCouAdminGroup(couId); if (group != null) { httpUtils.post("co_group_members.json", jsonUtils.coGroupMembers(group.get("Id").getAsInt(), coPersonId, true)); @@ -418,7 +420,7 @@ public class RegistryCalls implements AaiRegistryService { } @Override - public void removeAdminRole(Integer coPersonId, Integer couId) { + public void removeAdminRole(Integer coPersonId, Integer couId) throws RestClientException { JsonObject adminGroup = this.getCouAdminGroup(couId); JsonArray admins = this.getGroupMembers(adminGroup.get("Id").getAsInt()); Integer id = null; diff --git a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/HttpUtils.java b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/HttpUtils.java index b294717..07b2f72 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/HttpUtils.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/aai/registry/utils/HttpUtils.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; @@ -32,7 +33,7 @@ public class HttpUtils { @Value("${services.provide.aai.registry.password}") private String password; - public JsonElement post(String path, JsonObject body) { + public JsonElement post(String path, JsonObject body) throws RestClientException { RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = createHeaders(user, password); headers.setContentType(MediaType.APPLICATION_JSON); @@ -41,7 +42,7 @@ public class HttpUtils { return getResponseEntityAsJsonElement(responseEntity); } - public JsonElement put(String path, JsonObject body) { + public JsonElement put(String path, JsonObject body) throws RestClientException { RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = createHeaders(user, password); headers.setContentType(MediaType.APPLICATION_JSON); @@ -50,7 +51,7 @@ public class HttpUtils { return getResponseEntityAsJsonElement(responseEntity); } - public JsonElement get(String path, Map params) { + public JsonElement get(String path, Map params) throws RestClientException { RestTemplate restTemplate = new RestTemplate(); String url = createUrl(registryUrl + path, params); ResponseEntity responseEntity = restTemplate.exchange @@ -58,7 +59,7 @@ public class HttpUtils { return getResponseEntityAsJsonElement(responseEntity); } - public JsonElement delete(String path) { + public JsonElement delete(String path) throws RestClientException { RestTemplate restTemplate = new RestTemplate(); String url = registryUrl + path; ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, new HttpEntity<>(createHeaders(user, password)), String.class); diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java index 96c91d6..b9de706 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AaiRoleMappingService.java @@ -7,6 +7,8 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Service; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Collection; import java.util.Objects; @@ -20,21 +22,8 @@ public class AaiRoleMappingService implements RoleMappingService { @Value("${services.provide.aai.registry.production:true}") private boolean production; - - private String createRepoRoleName(String prefix, String repoId) { - return prefix + "." + repoId.replace(":", "$"); - } - @Override - public String getRepoNameWithoutType(String fullName, String prefix) { - if (fullName != null && prefix != null && fullName.startsWith(prefix)) { - return fullName.substring(prefix.length()); - } - return null; - } - - @Override - public String getRepoIdByRoleId(String roleId) { + public String getRepositoryId(String roleId) { if (!roleActive(roleId)) { return null; } @@ -42,43 +31,46 @@ public class AaiRoleMappingService implements RoleMappingService { } @Override - public Collection getRepoIdsByRoleIds(Collection roleIds) { + public Collection getRepositoryIds(Collection roleIds) { return roleIds .stream() - //.filter(this::roleActive) // implicitly executed in the next statement - .map(this::getRepoIdByRoleId) + .map(this::getRepositoryId) .filter(Objects::nonNull) .collect(Collectors.toList()); } @Override - public String getRoleIdByRepoId(String repoId) { - String roleId = ""; + public String getRole(String repoId) { + String role = null; String prefix = (production ? "" : "beta.") + "datasource"; if (repoId != null) { - roleId = createRepoRoleName(prefix, repoId); - return roleId; - } else { - return null; + role = createRole(prefix, repoId); } - + return role; } @Override - public Collection getRoleIdsByRepoIds(Collection repoIds) { + public Collection getRoles(Collection repoIds) { return repoIds .stream() - .map(this::getRoleIdByRepoId) + .map(this::getRole) .filter(Objects::nonNull) .collect(Collectors.toList()); } @Override - public String convertAuthorityIdToRepoId(String authorityId) { - String repo = ""; - if (authorityId != null && roleActive(authorityId)) { - repo = authorityId - .replaceFirst(".*datasource\\.", "") + public String authorityToRepositoryId(GrantedAuthority authority) { + String repo = null; + String auth = null; + try { + auth = URLDecoder.decode(authority.getAuthority(), "UTF-8").toLowerCase(); + } catch (UnsupportedEncodingException e) { + logger.error("", e); + } + + if (auth != null && roleActive(auth)) { + repo = auth + .replaceFirst(".*datasource\\_", "") .replace("$", ":") .toLowerCase(); } @@ -86,12 +78,26 @@ public class AaiRoleMappingService implements RoleMappingService { } @Override - public String convertAuthorityToRepoId(GrantedAuthority authority) { - return convertAuthorityIdToRepoId(authority.toString()); + public GrantedAuthority repositoryIdToAuthority(String repoId) { + String role = null; + try { + role = URLEncoder.encode(convertRepoIdToAuthorityId(repoId), "UTF-8"); + } catch (UnsupportedEncodingException e) { + logger.error("", e); + } + return new SimpleGrantedAuthority(role); } - @Override - public String convertRepoIdToAuthorityId(String repoId) { + private String createRole(String prefix, String repoId) { + return prefix + "." + repoId.replace(":", "$"); + } + + private boolean roleActive(String roleId) { + return (production && !roleId.toLowerCase().startsWith("beta")) + || (!production && roleId.toLowerCase().startsWith("beta")); + } + + private String convertRepoIdToAuthorityId(String repoId) { StringBuilder roleBuilder = new StringBuilder(); String role = ""; if (repoId != null) { @@ -102,20 +108,4 @@ public class AaiRoleMappingService implements RoleMappingService { } return role; } - - @Override - public String convertRepoIdToEncodedAuthorityId(String repoId) { - return URLEncoder.encode(convertRepoIdToAuthorityId(repoId)); - } - - @Override - public SimpleGrantedAuthority convertRepoIdToAuthority(String repoId) { - String role = convertRepoIdToEncodedAuthorityId(repoId); - return new SimpleGrantedAuthority(role); - } - - private boolean roleActive(String roleId) { - return (production && !roleId.toLowerCase().startsWith("beta.")) - || (!production && roleId.toLowerCase().startsWith("beta.")); - } } diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java index e1f66f9..8305236 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/AuthorizationServiceImpl.java @@ -1,9 +1,11 @@ package eu.dnetlib.repo.manager.service.security; import com.google.gson.JsonElement; +import eu.dnetlib.repo.manager.domain.PendingUserRole; import eu.dnetlib.repo.manager.domain.dto.Role; import eu.dnetlib.repo.manager.domain.dto.User; import eu.dnetlib.repo.manager.exception.ResourceNotFoundException; +import eu.dnetlib.repo.manager.repository.PendingUserRoleRepository; import eu.dnetlib.repo.manager.service.aai.registry.AaiRegistryService; import org.mitre.openid.connect.model.OIDCAuthenticationToken; import org.mitre.openid.connect.model.UserInfo; @@ -30,13 +32,16 @@ public class AuthorizationServiceImpl implements AuthorizationService { private final RoleMappingService roleMappingService; private final AaiRegistryService aaiRegistryService; private final AuthoritiesUpdater authoritiesUpdater; + private final PendingUserRoleRepository pendingUserRoleRepository; @Autowired AuthorizationServiceImpl(RoleMappingService roleMappingService, AaiRegistryService aaiRegistryService, - AuthoritiesUpdater authoritiesUpdater) { + AuthoritiesUpdater authoritiesUpdater, + PendingUserRoleRepository pendingUserRoleRepository) { this.roleMappingService = roleMappingService; this.aaiRegistryService = aaiRegistryService; this.authoritiesUpdater = authoritiesUpdater; + this.pendingUserRoleRepository = pendingUserRoleRepository; } private String mapType(String type) { @@ -56,9 +61,9 @@ public class AuthorizationServiceImpl implements AuthorizationService { @Override public boolean isMemberOf(String repoId) { - String repoRole = roleMappingService.convertRepoIdToEncodedAuthorityId(repoId); + String repoAuthority = roleMappingService.repositoryIdToAuthority(repoId).getAuthority(); return SecurityContextHolder.getContext().getAuthentication().getAuthorities() - .stream().anyMatch(authority -> authority.toString().equals(repoRole)); + .stream().anyMatch(authority -> authority.toString().equals(repoAuthority)); } @Override @@ -74,7 +79,7 @@ public class AuthorizationServiceImpl implements AuthorizationService { public List getAdminsOfRepo(String repoId) { // find couId by role name - String role = roleMappingService.getRoleIdByRepoId(repoId); + String role = roleMappingService.getRole(repoId); Integer couId = aaiRegistryService.getCouId(role); return aaiRegistryService.getUsers(couId); } @@ -82,26 +87,29 @@ public class AuthorizationServiceImpl implements AuthorizationService { @Override public void addAdmin(String resourceId, String email) throws ResourceNotFoundException { - String role = roleMappingService.getRoleIdByRepoId(resourceId); + String role = roleMappingService.getRole(resourceId); Integer couId = aaiRegistryService.getCouId(role); if (couId == null) { throw new ResourceNotFoundException("Cannot find CouId for role: " + role); } List coPersonIds = aaiRegistryService.getCoPersonIdsByEmail(email); + if (coPersonIds.isEmpty()) { + throw new ResourceNotFoundException("User with email '%s' could not be found.."); + } for (Integer coPersonId : coPersonIds) { assert coPersonId != null; aaiRegistryService.assignMemberRole(coPersonId, couId); // Add role to user current authorities for (String userId : aaiRegistryService.getUserIdentifiersByEmail(email)) { - authoritiesUpdater.addRole(userId, roleMappingService.convertRepoIdToAuthority(resourceId)); + authoritiesUpdater.addRole(userId, roleMappingService.repositoryIdToAuthority(resourceId)); } } } @Override public void removeAdmin(String resourceId, String email) throws ResourceNotFoundException { - String role = roleMappingService.getRoleIdByRepoId(resourceId); + String role = roleMappingService.getRole(resourceId); Integer couId = aaiRegistryService.getCouId(role); if (couId == null) { throw new ResourceNotFoundException("Cannot find CouId for role: " + role); @@ -115,7 +123,7 @@ public class AuthorizationServiceImpl implements AuthorizationService { // Remove role from user current authorities for (String userId : aaiRegistryService.getUserIdentifiersByEmail(email)) { - authoritiesUpdater.removeRole(userId, roleMappingService.convertRepoIdToAuthority(resourceId)); + authoritiesUpdater.removeRole(userId, roleMappingService.repositoryIdToAuthority(resourceId)); } } else { logger.error("Cannot find RoleId for role: {}", role); @@ -126,7 +134,7 @@ public class AuthorizationServiceImpl implements AuthorizationService { @Override public void createAndAssignRoleToAuthenticatedUser(String resourceId, String roleDescription) { // Create new role - String newRoleName = roleMappingService.getRoleIdByRepoId(resourceId); + String newRoleName = roleMappingService.getRole(resourceId); Role newRole = new Role(newRoleName, roleDescription); Integer couId; @@ -145,10 +153,15 @@ public class AuthorizationServiceImpl implements AuthorizationService { // Assign new role to the current authenticated user Integer coPersonId = aaiRegistryService.getCoPersonIdByIdentifier(); if (couId != null) { - aaiRegistryService.assignMemberRole(coPersonId, couId); + + try { + aaiRegistryService.assignMemberRole(coPersonId, couId); + } catch (Exception e) { + pendingUserRoleRepository.save(new PendingUserRole(coPersonId, couId)); + } // Add role to current user authorities - authoritiesUpdater.addRole(roleMappingService.convertRepoIdToAuthority(resourceId)); + authoritiesUpdater.addRole(roleMappingService.repositoryIdToAuthority(resourceId)); } } diff --git a/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java b/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java index 67439bf..c1a77c4 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/security/RoleMappingService.java @@ -7,68 +7,41 @@ import java.util.Collection; public interface RoleMappingService { - /** - * @param fullName - * @param prefix - * @return - */ - String getRepoNameWithoutType(String fullName, String prefix); - /** * @param roleId Role Id * @return Converts {@param roleId} to a repo Id. */ - String getRepoIdByRoleId(String roleId); + String getRepositoryId(String roleId); /** - * * @param roleIds Collection of roles * @return Converts {@param roleIds} to a repo Ids. */ - Collection getRepoIdsByRoleIds(Collection roleIds); + Collection getRepositoryIds(Collection roleIds); /** * @param repoId Repository Id * @return Converts {@param repoId} to a role Id. */ - String getRoleIdByRepoId(String repoId); + String getRole(String repoId); /** * @param repoIds Collection of Repository Ids * @return Converts {@param repoIds} to role Ids. */ - Collection getRoleIdsByRepoIds(Collection repoIds); + Collection getRoles(Collection repoIds); /** - * @param authorityId Authority Id - * @return Converts {@param authorityId} to repo Id. + * @param authority {@link GrantedAuthority} + * @return Converts {@param authority} to repository Id. */ - String convertAuthorityIdToRepoId(String authorityId); - - /** - * @param authority Granted authority - * @return Converts {@param authority} to repo Id. - */ - String convertAuthorityToRepoId(GrantedAuthority authority); - - /** - * @param repoId Repository Id - * @return - */ - String convertRepoIdToAuthorityId(String repoId); - - /** - * @param repoId Repository Id - * @return Converts {@param repoId} to {@link String} role id url encoded ($ -> %24) - * // TODO: remove role encoding and perform url decoding when mapping authorities. (Must be performed in all OpenAIRE projects because of Redis) - */ - String convertRepoIdToEncodedAuthorityId(String repoId); + String authorityToRepositoryId(GrantedAuthority authority); /** * @param repoId Repository Id * @return Converts {@param repoId} to {@link SimpleGrantedAuthority} with the role url encoded ($ -> %24) * // TODO: remove role encoding and perform url decoding when mapping authorities. (Must be performed in all OpenAIRE projects because of Redis) */ - SimpleGrantedAuthority convertRepoIdToAuthority(String repoId); + GrantedAuthority repositoryIdToAuthority(String repoId); } diff --git a/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteR5Service.java b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteR5Service.java new file mode 100644 index 0000000..662d123 --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteR5Service.java @@ -0,0 +1,27 @@ +package eu.dnetlib.repo.manager.service.sushilite; + +import org.json.JSONException; +import org.springframework.http.ResponseEntity; + +import java.util.List; + +public interface SushiliteR5Service { + + + ResponseEntity getReportResults(String Report, + String release, + String requestorID, + String beginDate, + String endDate, + String repositoryIdentifier, + String datasetIdentifier, + String itemIdentifier, + List metricTypes, + String dataType, + String granularity, + String pretty) throws JSONException; + + + + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteR5ServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteR5ServiceImpl.java new file mode 100644 index 0000000..868d17e --- /dev/null +++ b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteR5ServiceImpl.java @@ -0,0 +1,135 @@ +package eu.dnetlib.repo.manager.service.sushilite; + +//import eu.dnetlib.usagestats.sushilite.domain.COUNTER_Item_Report; +import org.json.JSONException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; +import java.util.List; + +@Service("sushiliteR5Service") +public class SushiliteR5ServiceImpl implements SushiliteR5Service { + + private static final Logger logger = LoggerFactory.getLogger(SushiliteR5ServiceImpl.class); + + + @Value("${services.provide.usagestats.sushiliteR5Endpoint}") + private String usagestatsSushiliteR5Endpoint; + + + public ResponseEntity getReportResults(String report, + String release, + String requestorID, + String beginDate, + String endDate, + String repositoryIdentifier, + String datasetIdentifier, + String itemIdentifier, + List metricTypes, + String dataType, + String granularity, + String pretty) throws JSONException + { + //build the uri params + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(this.usagestatsSushiliteR5Endpoint + "reports/" + report.toLowerCase()) + .queryParam("Report", report) + .queryParam("Release", release) + .queryParam("RequestorID", requestorID) + .queryParam("BeginDate", beginDate) + .queryParam("EndDate", endDate) + .queryParam("RepositoryIdentifier", repositoryIdentifier) + .queryParam("DatasetIdentifier", datasetIdentifier) + .queryParam("ItemIdentifier", itemIdentifier); + if ( metricTypes != null ) { + for ( String metricType : metricTypes ) + builder.queryParam("MetricType", metricType); + } + builder.queryParam("DataType", dataType) + .queryParam("Granularity", granularity) + .queryParam("Pretty", pretty); + + URI uri = builder.build().encode().toUri(); + + RestTemplate restTemplate = new RestTemplate(); + restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); + + ResponseEntity resp; + try { + resp = restTemplate.exchange( + uri, + HttpMethod.GET, + null, + new ParameterizedTypeReference() {}); // THis "Object" must be a valid json-object. + } catch (RestClientException rce) { + String errorMsg = "Failed to get a response from sushiliteR5!"; + String message = rce.getMessage(); + if ( (message != null) && message.contains("504 Gateway Time-out") ) // In this case the parsing-exception is thrown before we get to check the response code.. + errorMsg += " Reason: 504 Gateway Time-out"; + + logger.error(errorMsg + " URI was:\n" + uri + "\n" + message); + return ResponseEntity.internalServerError().body(errorMsg); + } + + HttpStatus httpStatus = resp.getStatusCode(); + if ( httpStatus != HttpStatus.OK ) { + logger.warn("Sushi cannot give us data! Responded status: " + httpStatus); + return ResponseEntity.status(httpStatus).build(); + } + + Object reportResult = resp.getBody(); + if ( reportResult == null ) { + logger.error("The \"reportResponseWrapper\" for sushi was null!"); + return ResponseEntity.internalServerError().build(); + } + logger.trace(reportResult.toString()); + + return ResponseEntity.ok(reportResult); + + + + // TODO - Depending on the "report-type", map the "object" to the right Report-type class. + // TODO - This will be useful, in case we add preprocessing steps, like pagination. +/* try { + switch ( report ) { + case "PR": + + break; + case "PR_P1": + + break; + case "IR": + COUNTER_Item_Report counterItemReport = (COUNTER_Item_Report) resp.getBody(); + if ( counterItemReport == null ) { + logger.error("The \"reportResponseWrapper\" for sushi was null!"); + return ResponseEntity.internalServerError().build(); + } else { + logger.debug(counterItemReport.toString()); + return ResponseEntity.ok(counterItemReport); + } + case "DSR": + + break; + default: + String errorMsg = "Invalid report type was given: " + report; + logger.error(errorMsg); + return ResponseEntity.badRequest().body(errorMsg); + } + } catch (ClassCastException cce) { + logger.error("The report object could not be mapped to the repo-type-object of \"" + report + "\"!", cce); + return ResponseEntity.internalServerError().build(); + }*/ + + } + +} diff --git a/src/main/java/eu/dnetlib/repo/manager/service/SushiliteService.java b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteService.java similarity index 94% rename from src/main/java/eu/dnetlib/repo/manager/service/SushiliteService.java rename to src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteService.java index 15ea811..fe247ff 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/SushiliteService.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteService.java @@ -1,4 +1,4 @@ -package eu.dnetlib.repo.manager.service; +package eu.dnetlib.repo.manager.service.sushilite; import eu.dnetlib.usagestats.sushilite.domain.ReportResponseWrapper; import org.json.JSONException; diff --git a/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteServiceImpl.java similarity index 96% rename from src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java rename to src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteServiceImpl.java index ba41dda..d38c306 100644 --- a/src/main/java/eu/dnetlib/repo/manager/service/SushiliteServiceImpl.java +++ b/src/main/java/eu/dnetlib/repo/manager/service/sushilite/SushiliteServiceImpl.java @@ -1,4 +1,4 @@ -package eu.dnetlib.repo.manager.service; +package eu.dnetlib.repo.manager.service.sushilite; import eu.dnetlib.usagestats.sushilite.domain.Customer; import eu.dnetlib.usagestats.sushilite.domain.ReportItem; @@ -93,8 +93,8 @@ public class SushiliteServiceImpl implements SushiliteService { List requestedItemList = new ArrayList<>(); Customer customer = reportResponseWrapper.getReportResponse().getReportWrapper().getReport().getCustomer(); - List allReportItems = customer.getReportItems(); + List allReportItems = customer.getReportItems(); if ( allReportItems != null ) { try { int totalItems = allReportItems.size(); @@ -111,9 +111,9 @@ public class SushiliteServiceImpl implements SushiliteService { logger.error("Exception on getReportResults - trying to cast strings to integers", e); throw e; } - } - customer.setReportItems(requestedItemList); // Setting the reportItems to the "customer"-reference, updates the "reportResponseWrapper" object. + customer.setReportItems(requestedItemList); // Setting the reportItems to the "customer"-reference, updates the "reportResponseWrapper" object. + } return reportResponseWrapper; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 93e95cb..5b3a5d5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,15 @@ -springdoc.swagger-ui: - disable-swagger-default-url: true - version: 3 +server: + port: 8480 + servlet: + context-path: /uoa-repository-manager-service + +springdoc: + swagger-ui: + disable-swagger-default-url: true + path: /swagger-ui.html + displayRequestDuration: true + api-docs: + path: /api-docs spring: jpa: @@ -14,11 +23,11 @@ spring: driverClassName: ${services.provide.db.driverClassName} services: - openaireServicesBaseUrl: https://beta.services.openaire.eu + openaireServicesBaseUrl: https://beta.services.openaire.eu # dev-openaire.d4science.org provide: dev-machine: 88.197.53.71 # VM-71 aai: - baseURL: https://beta.aai.openaire.eu + baseURL: https://aai.openaire.eu oidc: domain: .openaire.eu # use empty value for local, otherwise: ".openaire.eu" id: XX @@ -34,14 +43,14 @@ services: url: ${services.provide.aai.baseURL}/registry/ adminEmail: XX analyticsURL: https://analytics.openaire.eu/addsite.php? - baseUrl: https://dev-openaire.d4science.org/openaire + baseUrl: ${services.openaireServicesBaseUrl}/openaire broker: api: api/ openaire: openaireBroker port: 443 url: https://beta.broker.openaire.eu clients: - dsm: https://dev-openaire.d4science.org/openaire + dsm: ${services.provide.baseUrl} search: ${services.openaireServicesBaseUrl}/search/v2/api usageEvents: http://beta.lbs.openaire.eu:8080/ajax/summary usagestats: ${services.openaireServicesBaseUrl}/usagestats @@ -67,12 +76,14 @@ services: password: XX port: 6379 topic_types: - url: ${services.openaireServicesBaseUrl}/provision/mvc/vocabularies/dnet:topic_types.json + url: ${services.openaireServicesBaseUrl}/provision/mvc/vocabularies/dnet:topic_types.json # TODO - Check this! The requested json file does not exist in the DEV-url below) + # https://dev-openaire.d4science.org/provision/mvc/vocabularies/ usageStatisticsDiagramsBaseURL: https://beta.openaire.eu/stats3/ usageStatisticsNumbersBaseURL: ${services.openaireServicesBaseUrl}/usagestats/datasources/ usagestats: adminEmail: XX sushiliteEndpoint: ${services.openaireServicesBaseUrl}/usagestats/sushilite/ + sushiliteR5Endpoint: ${services.openaireServicesBaseUrl}/usagestats_r5/sushilite/r5/ validator: results: url: https://beta.provide.openaire.eu/compatibility/browseHistory/ diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 2e6c355..45fb4a8 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -15,8 +15,5 @@ - - -