diff --git a/api/pom.xml b/api/pom.xml index 54562441993b87ce306d27e02e0158e5adcacf64..6a1cc8c187d62eba60d8d12cb39ff927cef744d7 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -1,115 +1,105 @@ +<?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>com.indiscale.fdo</groupId> - <artifactId>fdo-manager-service</artifactId> - <version>0.1.0-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <project.build.outputEncoding>UTF-8</project.build.outputEncoding> - <sourceDir>/src/main/java/</sourceDir> - <apiBasePackage>${project.groupId}.manager.service.api</apiBasePackage> - </properties> - - <artifactId>fdo-manager-service.api</artifactId> - <packaging>jar</packaging> - <name>${project.artifactId}</name> - - <dependencies> - - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - </dependency> - - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-validation</artifactId> - </dependency> - - <dependency> - <groupId>org.openapitools</groupId> - <artifactId>jackson-databind-nullable</artifactId> - <version>0.2.6</version> - </dependency> - <dependency> - <groupId>io.swagger.core.v3</groupId> - <artifactId>swagger-annotations</artifactId> - <version>2.2.20</version> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> <!--https://openapi-generator.tech/docs/plugins/--> - <groupId>org.openapitools</groupId> - <artifactId>openapi-generator-maven-plugin</artifactId> - <version>7.2.0</version> - <executions> - <execution> - <goals> - <goal>generate</goal> - </goals> - <id>buildApi</id> - <configuration> - <inputSpec>${basedir}/src/main/resources/api.yaml</inputSpec> - <generatorName>spring</generatorName> - <!--<library>spring-boot</library>--> - <modelNameSuffix></modelNameSuffix> - - <generateApis>true</generateApis> - <generateApiTests>false</generateApiTests> - <generateApiDocumentation>false</generateApiDocumentation> - <generateModels>true</generateModels> - <generateModelTests>false</generateModelTests> - <generateModelDocumentation>false</generateModelDocumentation> - <generateSupportingFiles>false</generateSupportingFiles> - - <environmentVariables> - <supportingFiles> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.indiscale.fdo</groupId> + <artifactId>fdo-manager-service</artifactId> + <version>0.1.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.build.outputEncoding>UTF-8</project.build.outputEncoding> + <sourceDir>/src/main/java/</sourceDir> + <apiBasePackage>${project.groupId}.manager.service.api</apiBasePackage> + </properties> + <artifactId>fdo-manager-service.api</artifactId> + <packaging>jar</packaging> + <name>${project.artifactId}</name> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>org.openapitools</groupId> + <artifactId>jackson-databind-nullable</artifactId> + <version>0.2.6</version> + </dependency> + <dependency> + <groupId>io.swagger.core.v3</groupId> + <artifactId>swagger-annotations</artifactId> + <version>2.2.20</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <!--https://openapi-generator.tech/docs/plugins/--> + <groupId>org.openapitools</groupId> + <artifactId>openapi-generator-maven-plugin</artifactId> + <version>7.3.0</version> + <executions> + <execution> + <goals> + <goal>generate</goal> + </goals> + <id>buildApi</id> + <configuration> + <inputSpec>${basedir}/src/main/resources/api.yaml</inputSpec> + <generatorName>spring</generatorName> + <!--<library>spring-boot</library>--> + <modelNameSuffix/> + <generateApis>true</generateApis> + <generateApiTests>false</generateApiTests> + <generateApiDocumentation>false</generateApiDocumentation> + <generateModels>true</generateModels> + <generateModelTests>false</generateModelTests> + <generateModelDocumentation>false</generateModelDocumentation> + <generateSupportingFiles>false</generateSupportingFiles> + <environmentVariables> + <supportingFiles> ApiUtil.java </supportingFiles> - </environmentVariables> - - <!-- pass any necessary config options --> - <configOptions> - <sourceFolder>${sourceDir}</sourceFolder> - <useBeanValidation>true</useBeanValidation> - <performBeanValidation>true</performBeanValidation> - <interfaceOnly>true</interfaceOnly> - <serializableModel>true</serializableModel> - <implFolder>${sourceDir}</implFolder> - <modelPackage>${apiBasePackage}.model</modelPackage> - <apiPackage>${apiBasePackage}.operation</apiPackage> - <useSpringBoot3>true</useSpringBoot3> - </configOptions> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <configuration> - <archive> - <addMavenDescriptor>false</addMavenDescriptor> - <manifest> - <addClasspath>false</addClasspath> - <classpathPrefix>lib/</classpathPrefix> - <addDefaultImplementationEntries>true</addDefaultImplementationEntries> - </manifest> - <manifestEntries> - <Build-Number>${buildNumber}</Build-Number> - <Build-Time>${maven.build.timestamp}</Build-Time> - </manifestEntries> - </archive> - </configuration> - </plugin> - </plugins> - </build> + </environmentVariables> + <!-- pass any necessary config options --> + <configOptions> + <sourceFolder>${sourceDir}</sourceFolder> + <useBeanValidation>true</useBeanValidation> + <performBeanValidation>true</performBeanValidation> + <interfaceOnly>true</interfaceOnly> + <serializableModel>true</serializableModel> + <implFolder>${sourceDir}</implFolder> + <modelPackage>${apiBasePackage}.model</modelPackage> + <apiPackage>${apiBasePackage}.operation</apiPackage> + <useSpringBoot3>true</useSpringBoot3> + </configOptions> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <addMavenDescriptor>false</addMavenDescriptor> + <manifest> + <addClasspath>false</addClasspath> + <classpathPrefix>lib/</classpathPrefix> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Build-Number>${buildNumber}</Build-Number> + <Build-Time>${maven.build.timestamp}</Build-Time> + </manifestEntries> + </archive> + </configuration> + </plugin> + </plugins> + </build> </project> diff --git a/api/src/main/resources/api.yaml b/api/src/main/resources/api.yaml index e2637ab651bfd64f2de09a0a7cdfb29270cec42a..5ab51315dca1df7fe7a04c6c0495eb82b949fcbb 100644 --- a/api/src/main/resources/api.yaml +++ b/api/src/main/resources/api.yaml @@ -34,6 +34,38 @@ paths: links: $ref: '#/components/schemas/Links' + /profiles/{profileId}: + get: + tags: + - Profiles + summary: "Get information on a single profile." + operationId: getProfile + parameters: + - name: profileId + in: path + description: "Profile ID" + required: true + schema: + $ref: '#/components/schemas/ProfileID' + responses: + 200: + description: "Success." + content: + application/json: + schema: + type: object + required: ["data"] + properties: + data: + $ref: '#/components/schemas/Profile' + links: + $ref: '#/components/schemas/Links' + 404: + description: "Unknown profile id." + content: + application/json: + schema: + $ref: '#/components/schemas/Error' /hello: get: summary: Say hello to the server. @@ -310,10 +342,10 @@ components: Links: type: object - nullable: true properties: self: type: string + nullable: true collection: type: string nullable: true @@ -334,21 +366,21 @@ components: - "gwdg-cordra-1" - "fdo.indiscale.com" - "b2share@gwdg" - ProfileID: - type: string - nullable: true - Profile: + Repository: type: object properties: id: - $ref: '#/components/schemas/ProfileID' + $ref: '#/components/schemas/RepositoryID' links: $ref: '#/components/schemas/Links' - Repository: + ProfileID: + type: string + nullable: true + Profile: type: object properties: id: - $ref: '#/components/schemas/RepositoryID' + $ref: '#/components/schemas/ProfileID' links: $ref: '#/components/schemas/Links' Hello: diff --git a/application/pom.xml b/application/pom.xml index 3082c1985db63d84fe3c39adea8740dd18ea0ce2..b8ddea04bd238003a447973854857b1ed435f67c 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -1,139 +1,104 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <groupId>com.indiscale.fdo</groupId> - <artifactId>fdo-manager-service</artifactId> - <version>0.1.0-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <modelVersion>4.0.0</modelVersion> - - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <project.build.outputEncoding>UTF-8</project.build.outputEncoding> - <sourceDir>${project.basedir}/src/main</sourceDir> - <fdo.sdk.version>0.1.0-SNAPSHOT</fdo.sdk.version> - </properties> - - <artifactId>fdo-manager-service.application</artifactId> - - <dependencies> - <dependency> - <groupId>com.indiscale.fdo</groupId> - <artifactId>fdo-manager-sdk</artifactId> - <version>${fdo.sdk.version}</version> - </dependency> - - <dependency> - <groupId>${project.groupId}</groupId> - <artifactId>${project.parent.artifactId}.api</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-test</artifactId> - </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-hateoas</artifactId> - </dependency> - - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-web</artifactId> - </dependency> - <dependency> - <groupId>org.springdoc</groupId> - <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> - <version>2.3.0</version> - </dependency> - - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context-support</artifactId> - </dependency> - </dependencies> - - <repositories> - <repository> - <id>gitlab-maven</id> - <url>https://gitlab.indiscale.com/api/v4/projects/229/packages/maven</url> - </repository> -</repositories> - -<distributionManagement> - <repository> - <id>gitlab-maven</id> - <url>https://gitlab.indiscale.com/api/v4/projects/229/packages/maven</url> - </repository> - - <snapshotRepository> - <id>gitlab-maven</id> - <url>https://gitlab.indiscale.com/api/v4/projects/229/packages/maven</url> - </snapshotRepository> -</distributionManagement> - +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>com.indiscale.fdo</groupId> + <artifactId>fdo-manager-service</artifactId> + <version>0.1.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.build.outputEncoding>UTF-8</project.build.outputEncoding> + <sourceDir>${project.basedir}/src/main</sourceDir> + <fdo.sdk.version>0.1.0-SNAPSHOT</fdo.sdk.version> + </properties> + <artifactId>fdo-manager-service.application</artifactId> + <dependencies> + <dependency> + <groupId>com.indiscale.fdo</groupId> + <artifactId>fdo-manager-sdk</artifactId> + <version>${fdo.sdk.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>${project.parent.artifactId}.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-hateoas</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springdoc</groupId> + <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> + <version>2.3.0</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context-support</artifactId> + </dependency> + <dependency> + <groupId>com.github.chrisvest</groupId> + <artifactId>stormpot</artifactId> + <version>3.1</version> + </dependency> + </dependencies> + <repositories> + <repository> + <id>gitlab-maven</id> + <url>https://gitlab.indiscale.com/api/v4/projects/229/packages/maven</url> + </repository> + </repositories> + <distributionManagement> + <repository> + <id>gitlab-maven</id> + <url>https://gitlab.indiscale.com/api/v4/projects/229/packages/maven</url> + </repository> + <snapshotRepository> + <id>gitlab-maven</id> + <url>https://gitlab.indiscale.com/api/v4/projects/229/packages/maven</url> + </snapshotRepository> + </distributionManagement> <build> <resources> <resource> <directory>${sourceDir}/resources</directory> - <filtering>true</filtering> </resource> </resources> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-resources-plugin</artifactId> - <version>3.3.1</version> - <configuration> - <filtering>true</filtering> - </configuration> - </plugin> - <plugin> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-maven-plugin</artifactId> - <configuration> - <mainClass>${project.groupId}.manager.service.Application</mainClass> - <skip>false</skip> - </configuration> - <executions> - <execution> - <goals> - <goal>repackage</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-dependency-plugin</artifactId> - <executions> - <execution> - <id>copy-api-specification-yaml</id> - <phase>prepare-package</phase> - <goals> - <goal>unpack</goal> - </goals> - <configuration> - <artifactItems> - <artifactItem> - <groupId>${project.groupId}</groupId> - <artifactId>${project.parent.artifactId}.api</artifactId> - <type>jar</type> - <overWrite>true</overWrite> - <outputDirectory>${project.build.directory}/classes/static/</outputDirectory> - </artifactItem> - </artifactItems> - <includes>**/api.yaml</includes> - </configuration> - </execution> - </executions> - </plugin> - - </plugins> - </build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>3.3.1</version> + <configuration> + <filtering>true</filtering> + </configuration> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <mainClass>${project.groupId}.manager.service.Application</mainClass> + <skip>false</skip> + </configuration> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/Application.java b/application/src/main/java/com/indiscale/fdo/manager/service/Application.java index a6bda4ec48d8a5de41cbe92b8459324984987bd1..85a8cf289edca84ebe97dc9d927d3fde23760e20 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/Application.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/Application.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class); - } + public static void main(String[] args) { + SpringApplication.run(Application.class); + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/BaseController.java b/application/src/main/java/com/indiscale/fdo/manager/service/BaseController.java index 0b4c61c826d3632b85f6733077c2366b2fb01f83..e3dc758a0dc9a82fba822ccba2d367ffaf72e606 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/BaseController.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/BaseController.java @@ -1,32 +1,54 @@ package com.indiscale.fdo.manager.service; + import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; +import com.indiscale.fdo.api.Manager; +import com.indiscale.fdo.manager.service.api.model.Error; +import com.indiscale.fdo.manager.service.api.model.Links; +import com.indiscale.fdo.manager.service.authentication.AuthToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.hateoas.IanaLinkRelations; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.server.ResponseStatusException; -import com.indiscale.fdo.manager.service.api.model.Error; -import com.indiscale.fdo.manager.service.api.model.Links; - public class BaseController { - @ExceptionHandler(ResponseStatusException.class) - public ResponseEntity<?> handleResponseStatusException(ResponseStatusException ex, WebRequest request) { - Error body = new Error().status(Integer.toString(ex.getStatusCode().value())).detail(ex.getReason()); - return ResponseEntity.status(ex.getStatusCode()).body(body); - } - - public <T> T getOperations(Class<T> controllerClass) { - return methodOn(controllerClass); - } - - public String link(Object object) { - return linkTo(object).withSelfRel().getHref(); - } - - public Links linkSelf(Object object) { - return new Links().self(link(object)); - } -} \ No newline at end of file + @Autowired ManagerPool managerPool; + + @Autowired AuthToken authToken; + + protected Manager getManager() { + return managerPool.getManager(); + } + + protected String getToken() { + return authToken.getToken(); + } + + @ExceptionHandler(ResponseStatusException.class) + public ResponseEntity<?> handleResponseStatusException( + ResponseStatusException ex, WebRequest request) { + Error body = + new Error().status(Integer.toString(ex.getStatusCode().value())).detail(ex.getReason()); + return ResponseEntity.status(ex.getStatusCode()).body(body); + } + + public <T> T getOperations(Class<T> controllerClass) { + return methodOn(controllerClass); + } + + public String link(Object object) { + return linkTo(object).withSelfRel().getHref(); + } + + public Links linkSelf(Object object) { + return new Links().self(link(object)); + } + + public Links linkCollection(Object object) { + return new Links().collection(linkTo(object).withRel(IanaLinkRelations.COLLECTION).getHref()); + } +} diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/HeaderInterceptorConfig.java b/application/src/main/java/com/indiscale/fdo/manager/service/HeaderInterceptorConfig.java index a2974bc2a185cf9d507ce7f8bf2f5e6ab81534ab..ecc56055298446c748274174d249dc2638c835b7 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/HeaderInterceptorConfig.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/HeaderInterceptorConfig.java @@ -1,5 +1,7 @@ package com.indiscale.fdo.manager.service; +import com.indiscale.fdo.manager.service.authentication.AuthToken; +import com.indiscale.fdo.manager.service.authentication.AuthTokenInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @@ -8,26 +10,22 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import com.indiscale.fdo.manager.service.authentication.AuthToken; -import com.indiscale.fdo.manager.service.authentication.AuthTokenInterceptor; - @Configuration public class HeaderInterceptorConfig implements WebMvcConfigurer { - @Override - public void addInterceptors(final InterceptorRegistry registry) { - registry.addInterceptor(authTokenInterceptor()); - } + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(authTokenInterceptor()); + } - @Bean - AuthTokenInterceptor authTokenInterceptor() { - return new AuthTokenInterceptor(authToken()); - } - - @Bean - @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) - AuthToken authToken() { - return new AuthToken(); - } + @Bean + AuthTokenInterceptor authTokenInterceptor() { + return new AuthTokenInterceptor(authToken()); + } -} \ No newline at end of file + @Bean + @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) + AuthToken authToken() { + return new AuthToken(); + } +} diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/ManagerPool.java b/application/src/main/java/com/indiscale/fdo/manager/service/ManagerPool.java index 863095d9b231b8452416c1fc84e2b62d197ca968..1f0ba4613d6fc7d21389191889736b7b1454d8c9 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/ManagerPool.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/ManagerPool.java @@ -1,67 +1,98 @@ package com.indiscale.fdo.manager.service; -import java.util.Deque; -import java.util.concurrent.ConcurrentLinkedDeque; - -import org.springframework.stereotype.Service; - -import com.indiscale.fdo.api.Data; -import com.indiscale.fdo.api.DigitalObject; -import com.indiscale.fdo.api.FDO; +import com.indiscale.fdo.DelegatorManager; import com.indiscale.fdo.api.Manager; -import com.indiscale.fdo.api.Metadata; -import com.indiscale.fdo.api.RepositoryConnection; -import com.indiscale.fdo.api.RepositoryRegistry; import com.indiscale.fdo.manager.service.mock.MockManager; +import java.util.concurrent.TimeUnit; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; +import stormpot.Allocator; +import stormpot.Pool; +import stormpot.PoolException; +import stormpot.Poolable; +import stormpot.Slot; +import stormpot.Timeout; @Service public class ManagerPool { - - public static class PooledManager implements Manager, AutoCloseable { - - final private Manager delegate; - final private Deque<PooledManager> pool; - - public PooledManager(Deque<PooledManager> pool, Manager delegate) { - this.pool = pool; - this.delegate = delegate; - } - - @Override - public void close() { - this.pool.push(this); - } - - @Override - public FDO createFDO(RepositoryConnection repository, Data data, Metadata metadata) { - return delegate.createFDO(repository, data, metadata); - } - - @Override - public RepositoryRegistry getRepositoryRegistry() { - return delegate.getRepositoryRegistry(); - } - - @Override - public DigitalObject resolvePID(String pid) { - return delegate.resolvePID(pid); - } - - } - - private static Deque<PooledManager> pool = new ConcurrentLinkedDeque<>(); - - private Manager createManager(Deque<PooledManager> pool) { - // TODO - return new PooledManager(pool, new MockManager()); - } - - public Manager getManager() { - Manager manager = pool.poll(); - if(manager == null) { - manager = createManager(pool); - } - return manager; - } + public static class PooledManager extends DelegatorManager implements Poolable { + + private Slot slot; + + public PooledManager(Manager manager, Slot slot) { + super(manager); + this.slot = slot; + } + + @Override + public void release() { + this.slot.release(this); + } + + @Override + public void close() { + this.release(); + } + } + + public static class ManagerAllocator implements Allocator<PooledManager> { + + private ManagerFactory factory; + + public ManagerAllocator(ManagerFactory factory) { + this.factory = factory; + } + + @Override + public PooledManager allocate(Slot slot) throws Exception { + return new PooledManager(factory.create(), slot); + } + + @Override + public void deallocate(PooledManager poolable) throws Exception { + poolable.close(); + } + } + + public static class ManagerPoolTimeoutException extends Exception { + + private static final long serialVersionUID = -1400402103379045494L; + } + + public static interface ManagerFactory { + public Manager create(); + } + + private static Pool<PooledManager> pool = + Pool.from( + new ManagerAllocator( + new ManagerFactory() { + + @Override + public Manager create() { + return new MockManager(); + } + })) + .build(); + + Timeout timeout = new Timeout(5, TimeUnit.SECONDS); + + public Manager getManager() { + + try { + Manager manager = pool.claim(timeout); + if (manager == null) { + throw new ManagerPoolTimeoutException(); + } + return manager; + } catch (PoolException | InterruptedException e) { + e.printStackTrace(); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getLocalizedMessage()); + } catch (ManagerPoolTimeoutException e) { + throw new ResponseStatusException( + HttpStatus.REQUEST_TIMEOUT, "Service is under high load. Please try again later."); + } + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/ProcessDatabase.java b/application/src/main/java/com/indiscale/fdo/manager/service/ProcessDatabase.java index cac9265ea29aad7b809a645f9d86f4850cdc94b7..3a07ce12bde2de5d3e2a34664553105ac1fba3f3 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/ProcessDatabase.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/ProcessDatabase.java @@ -1,49 +1,44 @@ package com.indiscale.fdo.manager.service; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.springframework.stereotype.Repository; - import com.indiscale.fdo.manager.service.api.model.CreateFDOProcess; import com.indiscale.fdo.manager.service.api.model.CreateFDOProcessState; import com.indiscale.fdo.manager.service.api.model.CreateFDORequest; - import jakarta.validation.Valid; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.springframework.stereotype.Repository; class Process extends CreateFDOProcess { - private static final long serialVersionUID = -7495201524687733365L; - private @Valid CreateFDORequest createFDORequest; + private static final long serialVersionUID = -7495201524687733365L; + private @Valid CreateFDORequest createFDORequest; - public Process(String processId, @Valid CreateFDORequest createFDORequest) { - this.createFDORequest = createFDORequest; - this.setProcessId(processId); - this.setState(CreateFDOProcessState.PROCESSING); - this.setTargetRepository(createFDORequest.getTargetRepository()); - } - + public Process(String processId, @Valid CreateFDORequest createFDORequest) { + this.createFDORequest = createFDORequest; + this.setProcessId(processId); + this.setState(CreateFDOProcessState.PROCESSING); + this.setTargetRepository(createFDORequest.getTargetRepository()); + } } @Repository public class ProcessDatabase { - - static private Map<String, Process> map = new HashMap<>(); - - public String init(@Valid CreateFDORequest createFDORequest) { - String processId = UUID.randomUUID().toString(); - synchronized (map) { - map.put(processId, new Process(processId, createFDORequest)); - } - return processId; - } - - public CreateFDOProcess get(String processId) { - synchronized (map) { - Process process = map.get(processId); - return process; - } - } + private static Map<String, Process> map = new HashMap<>(); + + public String init(@Valid CreateFDORequest createFDORequest) { + String processId = UUID.randomUUID().toString(); + synchronized (map) { + map.put(processId, new Process(processId, createFDORequest)); + } + return processId; + } + + public CreateFDOProcess get(String processId) { + synchronized (map) { + Process process = map.get(processId); + return process; + } + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/RedirectBase.java b/application/src/main/java/com/indiscale/fdo/manager/service/RedirectBase.java index 7b88d14608f3a33af4186d2037443f6ae3988ac8..d455bddfa911d58e8b5d1876670dc96d9c7b941f 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/RedirectBase.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/RedirectBase.java @@ -10,13 +10,12 @@ import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/") public class RedirectBase { - - @Value("${springdoc.swagger-ui.path}") - private String swaggerUiPath; - - @GetMapping("/") - public ModelAndView redirectToSwaggerUi(ModelMap model) { - System.out.println("here:" + swaggerUiPath); - return new ModelAndView("forward:"+swaggerUiPath, model); - } -} \ No newline at end of file + + @Value("${springdoc.swagger-ui.path}") + private String swaggerUiPath; + + @GetMapping("/") + public ModelAndView redirectToSwaggerUi(ModelMap model) { + return new ModelAndView("forward:" + swaggerUiPath, model); + } +} diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthToken.java b/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthToken.java index eb0a06a33389ec9ce86134f59d45cd5e1c8dcd81..0f0f36d8a513b285c8a527efec502725af6c3b8b 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthToken.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthToken.java @@ -2,19 +2,18 @@ package com.indiscale.fdo.manager.service.authentication; public class AuthToken { - private String token; + private String token; - public void setToken(String token) { - this.token = token; - } - - public String getToken() { - return token; - } - - @Override - public String toString() { - return "AuthToken[" + token + "]"; - } + public void setToken(String token) { + this.token = token; + } + public String getToken() { + return token; + } + + @Override + public String toString() { + return "AuthToken[" + token + "]"; + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthTokenInterceptor.java b/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthTokenInterceptor.java index eda9f0871d8aee65c29278d0fa3110af5e3188fb..c0adfe091d3a2bcc91bf0b4668a231e93be5a890 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthTokenInterceptor.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/authentication/AuthTokenInterceptor.java @@ -1,35 +1,33 @@ package com.indiscale.fdo.manager.service.authentication; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.HandlerInterceptor; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - public class AuthTokenInterceptor implements HandlerInterceptor { - final private AuthToken authToken; + private final AuthToken authToken; - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - String header = request.getHeader("authentication"); - if(header != null && header.startsWith("Bearer ")) { - authToken.setToken(header.substring(7)); - } - return true; + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + String header = request.getHeader("authentication"); + if (header != null && header.startsWith("Bearer ")) { + authToken.setToken(header.substring(7)); } - - public AuthTokenInterceptor(AuthToken authToken) { - this.authToken = authToken; - } + return true; + } + + public AuthTokenInterceptor(AuthToken authToken) { + this.authToken = authToken; + } - @Bean - @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) - AuthToken authToken() { - return new AuthToken(); - } - - -} \ No newline at end of file + @Bean + @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) + AuthToken authToken() { + return new AuthToken(); + } +} diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/fdo/FDOApiImpl.java b/application/src/main/java/com/indiscale/fdo/manager/service/fdo/FDOApiImpl.java index b84134fb0a9005e33935727266e84953ca1acce6..2d8940bb792a9d560749eb3b39a0071f626db3a4 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/fdo/FDOApiImpl.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/fdo/FDOApiImpl.java @@ -2,84 +2,92 @@ package com.indiscale.fdo.manager.service.fdo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.server.ResponseStatusException; - -import com.indiscale.fdo.api.Data; +import com.indiscale.fdo.DefaultData; +import com.indiscale.fdo.DefaultMetadat; import com.indiscale.fdo.api.FDO; import com.indiscale.fdo.api.InputStreamSource; import com.indiscale.fdo.api.Manager; -import com.indiscale.fdo.api.Metadata; import com.indiscale.fdo.api.RepositoryConnection; import com.indiscale.fdo.api.UnknownRepositoryException; +import com.indiscale.fdo.api.ValidationException; import com.indiscale.fdo.manager.service.BaseController; -import com.indiscale.fdo.manager.service.ManagerPool; import com.indiscale.fdo.manager.service.api.model.TargetRepositories; import com.indiscale.fdo.manager.service.api.operation.FdoApi; -import com.indiscale.fdo.manager.service.authentication.AuthToken; - import jakarta.validation.Valid; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.server.ResponseStatusException; class MultipartFileWrapper implements InputStreamSource { - - private MultipartFile wrapped; - public MultipartFileWrapper(MultipartFile file) { - this.wrapped = file; - } + private MultipartFile wrapped; - @Override - public InputStream getInputStream() throws IOException { - return wrapped.getInputStream(); - } + public MultipartFileWrapper(MultipartFile file) { + this.wrapped = file; + } + + @Override + public InputStream getInputStream() throws IOException { + return wrapped.getInputStream(); + } } -class MetadataWrapper extends MultipartFileWrapper implements Metadata { - public MetadataWrapper(MultipartFile file) { - super(file); - } +class MetadataWrapper extends DefaultMetadat { + + private MultipartFile file; + + public MetadataWrapper(MultipartFile file) { + super(); + this.file = file; + } + @Override + public InputStream getInputStream() throws IOException { + return this.file.getInputStream(); + } } -class DataWrapper extends MultipartFileWrapper implements Data { +class DataWrapper extends DefaultData { - public DataWrapper(MultipartFile file) { - super(file); - } - + private MultipartFile file; + + public DataWrapper(MultipartFile file) { + super(); + this.file = file; + } + + @Override + public InputStream getInputStream() throws IOException { + return file.getInputStream(); + } } @RestController -@CrossOrigin(origins = {"${react-dev-server}"}, exposedHeaders = {"Location"}) +@CrossOrigin( + origins = {"${react-dev-server}"}, + exposedHeaders = {"Location"}) public class FDOApiImpl extends BaseController implements FdoApi { - - @Autowired - ManagerPool managerPool; - - @Autowired - AuthToken authToken; - - - @Override - public ResponseEntity<Void> createFDO(@Valid TargetRepositories repositories, MultipartFile data, - MultipartFile metadata) { - System.out.print("authToken: " + authToken.getToken()); - try (Manager manager = managerPool.getManager()) { - RepositoryConnection repository = manager.getRepositoryRegistry().createRepositoryConnection(repositories.getFdo()); - FDO fdo = manager.createFDO(repository, new DataWrapper(data), new MetadataWrapper(metadata)); - URI location = linkTo(getOperations(PIDApiImpl.class).resolvePID(fdo.getPID())).toUri(); - return ResponseEntity.created(location).build(); - } catch (UnknownRepositoryException e) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Not Found. Unknown repository id."); - } - } + + @Override + public ResponseEntity<Void> createFDO( + @Valid TargetRepositories repositories, MultipartFile data, MultipartFile metadata) { + System.out.print("authToken: " + getToken()); + try (Manager manager = getManager()) { + RepositoryConnection repository = + manager.getRepositoryRegistry().createRepositoryConnection(repositories.getFdo()); + FDO fdo = manager.createFDO(repository, new DataWrapper(data), new MetadataWrapper(metadata)); + URI location = linkTo(getOperations(PIDApiImpl.class).resolvePID(fdo.getPID())).toUri(); + return ResponseEntity.created(location).build(); + } catch (UnknownRepositoryException e) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Not Found. Unknown repository id."); + } catch (ValidationException e) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getValidationResult().toString()); + } + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/fdo/PIDApiImpl.java b/application/src/main/java/com/indiscale/fdo/manager/service/fdo/PIDApiImpl.java index f50d9c426836d4cefc96daafb4f87148b507ea6e..df469f39d2a4b95a88c15092b6ff425ac6d34e54 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/fdo/PIDApiImpl.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/fdo/PIDApiImpl.java @@ -1,44 +1,40 @@ package com.indiscale.fdo.manager.service.fdo; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.server.ResponseStatusException; - import com.indiscale.fdo.api.DigitalObject; import com.indiscale.fdo.api.Manager; import com.indiscale.fdo.manager.service.BaseController; -import com.indiscale.fdo.manager.service.ManagerPool; import com.indiscale.fdo.manager.service.api.model.Links; import com.indiscale.fdo.manager.service.api.model.ResolvePID200Response; import com.indiscale.fdo.manager.service.api.operation.PidApi; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; @RestController -@CrossOrigin(origins = {"${react-dev-server}"}) +@CrossOrigin(origins = {"${react-dev-server}"}) public class PIDApiImpl extends BaseController implements PidApi { - @Autowired - ManagerPool managerPool; + @Override + public ResponseEntity<ResolvePID200Response> resolvePID(String pid) { + try (Manager manager = getManager()) { + DigitalObject resolved = manager.resolvePID(pid); + if (resolved == null) { + throw new ResponseStatusException( + HttpStatus.NOT_FOUND, "Not found. Could not resolve PID."); + } - @Override - public ResponseEntity<ResolvePID200Response> resolvePID(String pid) { - try(Manager manager = managerPool.getManager()) { - DigitalObject resolved = manager.resolvePID(pid); - if (resolved == null) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Not found. Could not resolve PID."); - } - - return ResponseEntity.ok(createResponse(resolved)); - } - } + return ResponseEntity.ok(createResponse(resolved)); + } + } - private ResolvePID200Response createResponse(DigitalObject resolved) { - com.indiscale.fdo.manager.service.api.model.DigitalObject data = new com.indiscale.fdo.manager.service.api.model.DigitalObject(resolved.getPID(),resolved.isFDO()); - Links self = linkSelf(getOperations(getClass()).resolvePID(resolved.getPID())); - - return new ResolvePID200Response().data(data).links(self); - } + private ResolvePID200Response createResponse(DigitalObject resolved) { + com.indiscale.fdo.manager.service.api.model.DigitalObject data = + new com.indiscale.fdo.manager.service.api.model.DigitalObject( + resolved.getPID(), resolved.isFDO()); + Links self = linkSelf(getOperations(getClass()).resolvePID(resolved.getPID())); + return new ResolvePID200Response().data(data).links(self); + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/fdo/ProfilesApiImpl.java b/application/src/main/java/com/indiscale/fdo/manager/service/fdo/ProfilesApiImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..52db5683390c4d1509021476b6500b120da2afac --- /dev/null +++ b/application/src/main/java/com/indiscale/fdo/manager/service/fdo/ProfilesApiImpl.java @@ -0,0 +1,48 @@ +package com.indiscale.fdo.manager.service.fdo; + +import com.indiscale.fdo.api.FdoProfile; +import com.indiscale.fdo.api.Manager; +import com.indiscale.fdo.manager.service.BaseController; +import com.indiscale.fdo.manager.service.api.model.GetProfile200Response; +import com.indiscale.fdo.manager.service.api.model.Links; +import com.indiscale.fdo.manager.service.api.model.ListProfiles200Response; +import com.indiscale.fdo.manager.service.api.model.Profile; +import com.indiscale.fdo.manager.service.api.operation.ProfilesApi; +import java.util.List; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@CrossOrigin(origins = {"${react-dev-server}"}) +public class ProfilesApiImpl extends BaseController implements ProfilesApi { + + private Profile toProfile(FdoProfile p) { + return new Profile().id(p.getId()); + } + + @Override + public ResponseEntity<ListProfiles200Response> listProfiles() { + try (Manager manager = getManager()) { + List<FdoProfile> profiles = manager.getProfileRegistry().listProfiles(); + ListProfiles200Response result = new ListProfiles200Response(); + for (FdoProfile p : profiles) { + Links self = linkSelf(getOperations(getClass()).getProfile(p.getId())); + result.addDataItem(toProfile(p).links(self)); + } + Links self = linkSelf(getOperations(getClass()).listProfiles()); + + return ResponseEntity.ok(result.links(self)); + } + } + + @Override + public ResponseEntity<GetProfile200Response> getProfile(String profileId) { + try (Manager manager = getManager()) { + Profile profile = toProfile(manager.getProfileRegistry().getProfile(profileId)); + Links links = linkCollection(getOperations(getClass()).listProfiles()); + links.self(link(getOperations(getClass()).getProfile(profileId))); + return ResponseEntity.ok(new GetProfile200Response().data(profile).links(links)); + } + } +} diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/hello/HelloImpl.java b/application/src/main/java/com/indiscale/fdo/manager/service/hello/HelloImpl.java index c36de32d3b9c5c78b891b7dfc18d1c6a9ee172cd..33c212435736653253c352d0a4086e567b211f3a 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/hello/HelloImpl.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/hello/HelloImpl.java @@ -1,20 +1,18 @@ package com.indiscale.fdo.manager.service.hello; - -import com.indiscale.fdo.manager.service.api.operation.HelloApi; import com.indiscale.fdo.manager.service.api.model.Hello; +import com.indiscale.fdo.manager.service.api.operation.HelloApi; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RestController; @RestController -@CrossOrigin(origins = {"${react-dev-server}"}) +@CrossOrigin(origins = {"${react-dev-server}"}) public class HelloImpl implements HelloApi { - @Override - public ResponseEntity<Hello> hello() { - Hello hello = new Hello(); - hello.message("Hello from FDO Manager Service!"); - return ResponseEntity.ok(hello); - } - + @Override + public ResponseEntity<Hello> hello() { + Hello hello = new Hello(); + hello.message("Hello from FDO Manager Service!"); + return ResponseEntity.ok(hello); + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/hello/InfoImpl.java b/application/src/main/java/com/indiscale/fdo/manager/service/hello/InfoImpl.java index 9f3acace8b7b67775535ef7094590d9f7f85b89e..8e95008a6841d87b67c2e4a5b3196c70e3567bae 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/hello/InfoImpl.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/hello/InfoImpl.java @@ -1,33 +1,32 @@ package com.indiscale.fdo.manager.service.hello; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RestController; - import com.indiscale.fdo.manager.service.BaseController; import com.indiscale.fdo.manager.service.api.model.GetInfo200Response; import com.indiscale.fdo.manager.service.api.model.Info; import com.indiscale.fdo.manager.service.api.operation.InfoApi; import com.indiscale.fdo.manager.service.authentication.AuthToken; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RestController; @RestController -@CrossOrigin(origins = {"${react-dev-server}"}) +@CrossOrigin(origins = {"${react-dev-server}"}) public class InfoImpl extends BaseController implements InfoApi { - - @Autowired - AuthToken authToken; - @Value("${fdo.service.version}") - private String fdoServiceVersion; - @Value("${fdo.sdk.version}") - private String fdoSdkVersion; + @Autowired AuthToken authToken; + + @Value("${fdo.service.version}") + private String fdoServiceVersion; + + @Value("${fdo.sdk.version}") + private String fdoSdkVersion; - @Override - public ResponseEntity<GetInfo200Response> getInfo() { - System.out.println("authToken: " + authToken); - Info data = new Info().fdoServiceVersion(fdoServiceVersion).fdoSdkVersion(fdoSdkVersion); - return ResponseEntity.ok(new GetInfo200Response(data)); - } + @Override + public ResponseEntity<GetInfo200Response> getInfo() { + System.out.println("authToken: " + authToken); + Info data = new Info().fdoServiceVersion(fdoServiceVersion).fdoSdkVersion(fdoSdkVersion); + return ResponseEntity.ok(new GetInfo200Response(data)); + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockManager.java b/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockManager.java index 7f00e0ec610c44eeeb2f8cc7a238f5e886c0bd25..c07d2dc594f64b8501dd2798280620f7ba238003 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockManager.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockManager.java @@ -1,48 +1,96 @@ package com.indiscale.fdo.manager.service.mock; -import java.util.HashMap; -import java.util.Map; - import com.indiscale.fdo.DefaultManager; +import com.indiscale.fdo.DefaultProfileRegistry; import com.indiscale.fdo.DefaultRepositoryRegistry; import com.indiscale.fdo.api.Data; import com.indiscale.fdo.api.DigitalObject; import com.indiscale.fdo.api.FDO; +import com.indiscale.fdo.api.FdoProfile; import com.indiscale.fdo.api.Metadata; +import com.indiscale.fdo.api.ProfileValidator; import com.indiscale.fdo.api.RepositoryConnection; import com.indiscale.fdo.api.UnknownRepositoryTypeException; +import com.indiscale.fdo.api.ValidationError; +import com.indiscale.fdo.api.ValidationException; +import com.indiscale.fdo.api.ValidationResult; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class NoOpValidator implements ProfileValidator<FDO> { + + @Override + public ValidationResult validate(FDO t) { + return new ValidationResult() { + + @Override + public boolean isValid() { + return true; + } + + @Override + public List<ValidationError> getErrors() { + return Collections.emptyList(); + } + }; + } +} public class MockManager extends DefaultManager { - - private static Map<String, DigitalObject> pidRegistry = new HashMap<>(); - - public MockManager() { - MockRepositoryFactory mock = new MockRepositoryFactory(); - DefaultRepositoryRegistry registry = this.getRepositoryRegistry(); - registry.registerRepositoryType(mock); - try { - registry.registerRepository(mock.createMockConfig("mock-repo-1")); - registry.registerRepository(mock.createMockConfig("mock-repo-2")); - registry.registerRepository(mock.createMockConfig("mock-repo-3")); - } catch (UnknownRepositoryTypeException e) { - e.printStackTrace(); - } - } - - @Override - public FDO createFDO(RepositoryConnection repository, Data data, Metadata metadata) { - FDO fdo = super.createFDO(repository, data, metadata); - synchronized (pidRegistry) { - pidRegistry.put(fdo.getPID(), fdo); - } - return fdo; - } - - @Override - public DigitalObject resolvePID(String pid) { - synchronized (pidRegistry) { - return pidRegistry.get(pid); - } - } + private static Map<String, DigitalObject> pidRegistry = new HashMap<>(); + + public MockManager() { + MockRepositoryFactory mock = new MockRepositoryFactory(); + DefaultRepositoryRegistry registry = this.getRepositoryRegistry(); + registry.registerRepositoryType(mock); + try { + registry.registerRepository(mock.createMockConfig("mock-repo-1")); + registry.registerRepository(mock.createMockConfig("mock-repo-2")); + registry.registerRepository(mock.createMockConfig("mock-repo-3")); + } catch (UnknownRepositoryTypeException e) { + e.printStackTrace(); + } + DefaultProfileRegistry<FdoProfile> profileRegistry = getProfileRegistry(); + profileRegistry.registerProfile(createFdoProfile("mock-profile-1")); + } + + private FdoProfile createFdoProfile(final String id) { + return new FdoProfile() { + + @Override + public ProfileValidator<FDO> getValidator() { + return new NoOpValidator(); + } + + @Override + public String getId() { + return id; + } + }; + } + + @Override + public FDO createFDO(RepositoryConnection repository, Data data, Metadata metadata) + throws ValidationException { + FDO fdo = super.createFDO(repository, data, metadata); + synchronized (pidRegistry) { + pidRegistry.put(fdo.getPID(), fdo); + } + return fdo; + } + + @Override + public DigitalObject resolvePID(String pid) { + synchronized (pidRegistry) { + return pidRegistry.get(pid); + } + } + + @Override + public FdoProfile getDefaultProfile() { + return getProfileRegistry().listProfiles().get(0); + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockRepositoryFactory.java b/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockRepositoryFactory.java index 818c50e24a580cb02e0282e176bd73e3c161778f..eecd3e2c1e758c9b9e986609142fb32c764819b7 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockRepositoryFactory.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/mock/MockRepositoryFactory.java @@ -1,97 +1,103 @@ package com.indiscale.fdo.manager.service.mock; -import java.util.UUID; - -import com.indiscale.fdo.api.Data; +import com.indiscale.fdo.DelegatorFdo; import com.indiscale.fdo.api.FDO; -import com.indiscale.fdo.api.Metadata; -import com.indiscale.fdo.api.RepositoryConnection; import com.indiscale.fdo.api.RepositoryConfig; +import com.indiscale.fdo.api.RepositoryConnection; import com.indiscale.fdo.api.RepositoryConnectionFactory; import com.indiscale.fdo.api.RepositoryType; +import com.indiscale.fdo.api.ValidationException; +import java.util.UUID; class MockRepository implements RepositoryConnection { - public static class MockFDO implements FDO { - - private final String pid; - - public MockFDO() { - pid = UUID.randomUUID().toString(); - } - - @Override - public String getPID() { - return pid; - } - - } - private final String id; - private final RepositoryType type; - - public MockRepository(RepositoryConfig config) { - this.id = config.getId(); - this.type = config.getType(); - } - - @Override - public String getId() { - return id; - } - - @Override - public FDO createFDO(Data data, Metadata metadata) { - return new MockFDO(); - } - - @Override - public RepositoryType getType() { - return type; - } - - @Override - public void close() throws Exception { - } - + public static class MockFDO extends DelegatorFdo { + + private final String pid; + + public MockFDO(FDO fdo) { + super(fdo); + pid = UUID.randomUUID().toString(); + } + + @Override + public String getPID() { + return pid; + } + } + + private final String id; + private final RepositoryType type; + + public MockRepository(RepositoryConfig config) { + this.id = config.getId(); + this.type = config.getType(); + } + + @Override + public String getId() { + return id; + } + + @Override + public RepositoryType getType() { + return type; + } + + @Override + public void close() {} + + @Override + public boolean isOnline() { + return true; + } + + @Override + public FDO createFDO(FDO fdo) throws ValidationException { + return new MockFDO(fdo); + } } public class MockRepositoryFactory implements RepositoryConnectionFactory { - static class MockRepositoryConfig implements RepositoryConfig { - - private final String id; - - public MockRepositoryConfig(String id) { - this.id = id; - } - - @Override - public String getId() { - return id; - } - - @Override - public RepositoryType getType() { - return TYPE; - } - - } - - - public static final RepositoryType TYPE = new RepositoryType("MockDOIP").description("A mock-up for a DOIP repository."); - - @Override - public RepositoryConnection createConnection(RepositoryConfig config) { - return new MockRepository(config); - } - - @Override - public RepositoryType getType() { - return TYPE; - } - - public RepositoryConfig createMockConfig(String id) { - return new MockRepositoryConfig(id); - } + static class MockRepositoryConfig implements RepositoryConfig { + + private final String id; + + public MockRepositoryConfig(String id) { + this.id = id; + } + + @Override + public String getId() { + return id; + } + + @Override + public RepositoryType getType() { + return TYPE; + } + + @Override + public String get(String key) { + return null; + } + } + + public static final RepositoryType TYPE = + new RepositoryType("MockDOIP").description("A mock-up for a DOIP repository."); + + @Override + public RepositoryConnection createConnection(RepositoryConfig config) { + return new MockRepository(config); + } + + @Override + public RepositoryType getType() { + return TYPE; + } + public RepositoryConfig createMockConfig(String id) { + return new MockRepositoryConfig(id); + } } diff --git a/application/src/main/java/com/indiscale/fdo/manager/service/repositories/RepositoriesImpl.java b/application/src/main/java/com/indiscale/fdo/manager/service/repositories/RepositoriesImpl.java index e0bd551dcf1ec28099ce02eb577ce6c2ff70bfd1..cbd4e3b7f8687e4c258cc1be45bee283060f2a49 100644 --- a/application/src/main/java/com/indiscale/fdo/manager/service/repositories/RepositoriesImpl.java +++ b/application/src/main/java/com/indiscale/fdo/manager/service/repositories/RepositoriesImpl.java @@ -3,9 +3,16 @@ package com.indiscale.fdo.manager.service.repositories; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; +import com.indiscale.fdo.api.Manager; +import com.indiscale.fdo.api.RepositoryConfig; +import com.indiscale.fdo.api.UnknownRepositoryException; +import com.indiscale.fdo.manager.service.BaseController; +import com.indiscale.fdo.manager.service.api.model.GetRepository200Response; +import com.indiscale.fdo.manager.service.api.model.Links; +import com.indiscale.fdo.manager.service.api.model.ListRepositories200Response; +import com.indiscale.fdo.manager.service.api.operation.RepositoriesApi; import java.util.LinkedList; import java.util.List; - import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.http.HttpStatus; @@ -14,88 +21,78 @@ import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; -import com.indiscale.fdo.api.Manager; -import com.indiscale.fdo.api.RepositoryConfig; -import com.indiscale.fdo.api.UnknownRepositoryException; -import com.indiscale.fdo.manager.service.BaseController; -import com.indiscale.fdo.manager.service.ManagerPool; -import com.indiscale.fdo.manager.service.api.model.GetRepository200Response; -import com.indiscale.fdo.manager.service.api.model.Links; -import com.indiscale.fdo.manager.service.api.model.ListRepositories200Response; -import com.indiscale.fdo.manager.service.api.operation.RepositoriesApi; - @RestController -@CrossOrigin(origins = {"${react-dev-server}"}) +@CrossOrigin(origins = {"${react-dev-server}"}) public class RepositoriesImpl extends BaseController implements RepositoriesApi { - - static class Repository extends com.indiscale.fdo.manager.service.api.model.Repository { - private static final long serialVersionUID = -4753402740372027632L; - public Repository(RepositoryConfig config) { - this.setId(config.getId()); - } - - String getSelfRel() { - Link selfLink = linkTo(methodOn(RepositoriesImpl.class).getRepository(this.getId())).withSelfRel(); - return selfLink.getHref(); - } + static class Repository extends com.indiscale.fdo.manager.service.api.model.Repository { + private static final long serialVersionUID = -4753402740372027632L; + + public Repository(RepositoryConfig config) { + this.setId(config.getId()); + } + + String getSelfRel() { + Link selfLink = + linkTo(methodOn(RepositoriesImpl.class).getRepository(this.getId())).withSelfRel(); + return selfLink.getHref(); + } + + String getCollectionRel() { + Link collectionLink = + linkTo(methodOn(RepositoriesImpl.class).listRepositories()) + .withRel(IanaLinkRelations.COLLECTION); + return collectionLink.getHref(); + } + + public Repository withSelfRel() { + if (this.getLinks() == null) { + this.setLinks(new Links()); + } + this.getLinks().self(getSelfRel()); + return this; + } + + public Repository withCollectionRel() { + if (this.getLinks() == null) { + this.setLinks(new Links()); + } + this.getLinks().collection(getCollectionRel()); + return this; + } + } - String getCollectionRel() { - Link collectionLink = linkTo(methodOn(RepositoriesImpl.class).listRepositories()).withRel(IanaLinkRelations.COLLECTION); - return collectionLink.getHref(); - } - - public Repository withSelfRel() { - if (this.getLinks() == null) { - this.setLinks(new Links()); - } - this.getLinks().self(getSelfRel()); - return this; - } - - public Repository withCollectionRel() { - if (this.getLinks() == null) { - this.setLinks(new Links()); - } - this.getLinks().collection(getCollectionRel()); - return this; - } - } - - private ManagerPool factory; + @Override + public ResponseEntity<ListRepositories200Response> listRepositories() { + try (Manager manager = getManager()) { + List<com.indiscale.fdo.manager.service.api.model.Repository> results = new LinkedList<>(); - public RepositoriesImpl(ManagerPool factory) { - super(); - this.factory = factory; - } + List<RepositoryConfig> repositories = manager.getRepositoryRegistry().listRepositories(); + for (RepositoryConfig repo : repositories) { + results.add(new Repository(repo).withSelfRel()); + } - @Override - public ResponseEntity<ListRepositories200Response> listRepositories() { - try (Manager manager = factory.getManager()) { - List<com.indiscale.fdo.manager.service.api.model.Repository> results = new LinkedList<>(); - - List<RepositoryConfig> repositories = manager.getRepositoryRegistry().listRepositories(); - for (RepositoryConfig repo : repositories) { - results.add(new Repository(repo).withSelfRel()); - } + Link selfLink = linkTo(methodOn(getClass()).listRepositories()).withSelfRel(); + Links links = new Links(); + links.self(selfLink.getHref()); + return ResponseEntity.ok(new ListRepositories200Response().data(results).links(links)); + } + } - Link selfLink = linkTo(methodOn(getClass()).listRepositories()).withSelfRel(); - Links links = new Links(); - links.self(selfLink.getHref()); - return ResponseEntity.ok(new ListRepositories200Response().data(results).links(links)); - } - } + @Override + public ResponseEntity<GetRepository200Response> getRepository(String repositoryId) { - @Override - public ResponseEntity<GetRepository200Response> getRepository(String repositoryId) { - - try (Manager manager = factory.getManager()) { - RepositoryConfig config = manager.getRepositoryRegistry().getRepositoryConfig(repositoryId); + try (Manager manager = getManager()) { + RepositoryConfig config = manager.getRepositoryRegistry().getRepositoryConfig(repositoryId); - Repository repo = new Repository(config); - return ResponseEntity.ok(new GetRepository200Response().data(repo).links(new Links().self(repo.getSelfRel()).collection(repo.getCollectionRel()))); - } catch (UnknownRepositoryException e) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Unknown Repository ID: " + repositoryId); - } - } + Repository repo = new Repository(config); + return ResponseEntity.ok( + new GetRepository200Response() + .data(repo) + .links(new Links().self(repo.getSelfRel()).collection(repo.getCollectionRel()))); + } catch (UnknownRepositoryException e) { + throw new ResponseStatusException( + HttpStatus.NOT_FOUND, "Unknown Repository ID: " + repositoryId); + } + } } diff --git a/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloEmbeddedServerTest.java b/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloEmbeddedServerTest.java index b03ef853684df9528dfd573f8e5f9b5001443f41..8e522d0fd58bd488f6f26ca69df10d66ffa3324e 100644 --- a/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloEmbeddedServerTest.java +++ b/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloEmbeddedServerTest.java @@ -8,32 +8,29 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; -/** - * Test the HelloImpl class. - */ - +/** Test the HelloImpl class. */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class HelloEmbeddedServerTest { - @Autowired - private HelloImpl hello; + @Autowired private HelloImpl hello; - @LocalServerPort - private int port; + @LocalServerPort private int port; - @Autowired - private TestRestTemplate restTemplate; + @Autowired private TestRestTemplate restTemplate; - @Value("${server.servlet.context-path}") - private String contextPath; + @Value("${server.servlet.context-path}") + private String contextPath; - @Test - void index() { - Assertions.assertThat(hello).isNotNull(); - } + @Test + void index() { + Assertions.assertThat(hello).isNotNull(); + } - @Test - void indexResultTest() { - Assertions.assertThat(restTemplate.getForObject("http://localhost:" + port + contextPath + "/hello", String.class)).contains("Hello"); - } + @Test + void indexResultTest() { + Assertions.assertThat( + restTemplate.getForObject( + "http://localhost:" + port + contextPath + "/hello", String.class)) + .contains("Hello"); + } } diff --git a/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloMockMvcTest.java b/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloMockMvcTest.java index a12e0b7dac5ffeaf5f67962542e8094d8206be74..935bd68c065e65bb20d241a521163f84f540bf07 100644 --- a/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloMockMvcTest.java +++ b/application/src/test/java/com/indiscale/fdo/manager/service/hello/HelloMockMvcTest.java @@ -10,20 +10,15 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; -/** - * Test HelloImpl class (without embedded server). - */ +/** Test HelloImpl class (without embedded server). */ @SpringBootTest @AutoConfigureMockMvc public class HelloMockMvcTest { - @Autowired - private MockMvc mockMvc; + @Autowired private MockMvc mockMvc; - @Test - public void shouldReturnOurText() throws Exception { - this.mockMvc - .perform(get("/hello")) - .andExpect(content().string(containsString("Hello"))); - } + @Test + public void shouldReturnOurText() throws Exception { + this.mockMvc.perform(get("/hello")).andExpect(content().string(containsString("Hello"))); + } } diff --git a/application/src/test/java/com/indiscale/fdo/manager/service/repositories/RepositoriesTest.java b/application/src/test/java/com/indiscale/fdo/manager/service/repositories/RepositoriesTest.java index 6d29c76d75611b7dfa7f0a0dde387b57be833afa..b803b4b0ddf1cface4edd2aa27aa59d1df9c1950 100644 --- a/application/src/test/java/com/indiscale/fdo/manager/service/repositories/RepositoriesTest.java +++ b/application/src/test/java/com/indiscale/fdo/manager/service/repositories/RepositoriesTest.java @@ -1,8 +1,5 @@ package com.indiscale.fdo.manager.service.repositories; - - - import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -11,32 +8,29 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; -/** - * Test the {@link RepositoriesImpl} class - */ - +/** Test the {@link RepositoriesImpl} class */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class RepositoriesTest { - @Autowired - private RepositoriesImpl repositories; + @Autowired private RepositoriesImpl repositories; - @LocalServerPort - private int port; + @LocalServerPort private int port; - @Autowired - private TestRestTemplate restTemplate; + @Autowired private TestRestTemplate restTemplate; - @Value("${server.servlet.context-path}") - private String contextPath; + @Value("${server.servlet.context-path}") + private String contextPath; - @Test - void index() { - Assertions.assertThat(repositories).isNotNull(); - } + @Test + void index() { + Assertions.assertThat(repositories).isNotNull(); + } - @Test - void indexResultTest() { - Assertions.assertThat(restTemplate.getForObject("http://localhost:" + port + contextPath + "/repositories", String.class)).contains("data"); - } -} \ No newline at end of file + @Test + void indexResultTest() { + Assertions.assertThat( + restTemplate.getForObject( + "http://localhost:" + port + contextPath + "/repositories", String.class)) + .contains("data"); + } +} diff --git a/pom.xml b/pom.xml index 1b37a391796fe19423f5461f918923934e83fb01..33859146d49cb5293d5ad6c62af8397bb99fa9fe 100644 --- a/pom.xml +++ b/pom.xml @@ -1,31 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-parent</artifactId> - <version>3.2.2</version> - </parent> - - <groupId>com.indiscale.fdo</groupId> - <artifactId>fdo-manager-service</artifactId> - <packaging>pom</packaging> - <version>0.1.0-SNAPSHOT</version> - - <modules> - <module>api</module> - <module>application</module> - </modules> - - <properties> - <!-- this defines the java version for the project --> - <java.version>17</java.version> - </properties> - - <build> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>3.2.3</version> + </parent> + <groupId>com.indiscale.fdo</groupId> + <artifactId>fdo-manager-service</artifactId> + <packaging>pom</packaging> + <version>0.1.0-SNAPSHOT</version> + <modules> + <module>api</module> + <module>application</module> + </modules> + <properties> + <!-- this defines the java version for the project --> + <java.version>17</java.version> + </properties> + <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> @@ -34,7 +27,19 @@ <skip>true</skip> </configuration> </plugin> + <plugin> + <groupId>com.spotify.fmt</groupId> + <artifactId>fmt-maven-plugin</artifactId> + <version>2.22.1</version> + <executions> + <execution> + <phase>validate</phase> + <goals> + <goal>check</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> - </project>