diff --git a/.github/workflows/ecr.yml b/.github/workflows/ecr.yml index 8746cd4b..90b40339 100644 --- a/.github/workflows/ecr.yml +++ b/.github/workflows/ecr.yml @@ -6,6 +6,7 @@ on: push: branches: - develop + - ja-iss-14-drs-manifests # remove after confirming this works permissions: id-token: write jobs: @@ -45,8 +46,20 @@ jobs: with: registry: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com - - name: Build and push to ECR - id: build-and-push-to-ecr + - name: Build and push app to ECR + id: build-and-push-app-to-ecr + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ env.DOCKER_REPO }}:${{ env.DOCKER_TAG }} + ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ env.DOCKER_REPO }}:develop + ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ env.DOCKER_REPO }}:latest + + - name: Build and push liquibase to ECR + id: build-and-push-liquibase-to-ecr uses: docker/build-push-action@v6 with: context: liquibase diff --git a/Dockerfile b/Dockerfile index e68c4481..3865754a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,63 +1,24 @@ -################################################## -# BUILDER CONTAINER -################################################## +FROM gradle:9.5.1-jdk25-corretto AS builder -FROM openjdk:11.0.12 as builder +WORKDIR /home/gradle/project -USER root +COPY --chown=gradle:gradle build.gradle* settings.gradle* ./ +COPY --chown=gradle:gradle src ./src -WORKDIR /usr/src/dependencies +RUN gradle build -x test --no-daemon -# INSTALL MAKE -RUN apt update \ - && apt install build-essential -y +FROM amazoncorretto:25.0.3-alpine -# INSTALL SQLITE3 -RUN wget https://www.sqlite.org/2021/sqlite-autoconf-3340100.tar.gz \ - && tar -zxf sqlite-autoconf-3340100.tar.gz \ - && cd sqlite-autoconf-3340100 \ - && ./configure \ - && make \ - && make install +RUN addgroup -S appgroup && adduser -S appuser -G appgroup -# USER 'make' and 'sqlite3' to create the dev database -COPY Makefile Makefile -COPY database/sqlite database/sqlite -RUN make sqlite-db-refresh +WORKDIR /app -################################################## -# GRADLE CONTAINER -################################################## +COPY --from=builder /home/gradle/project/build/libs/*.jar app.jar -FROM gradle:7.3.3-jdk11 as gradleimage +RUN chown -R appuser:appgroup /app -WORKDIR /home/gradle/source +USER appuser -COPY build.gradle build.gradle -COPY gradlew gradlew -COPY settings.gradle settings.gradle -COPY src src -COPY src/main/resources/application.yml /app/application.yml +EXPOSE 8080 -RUN gradle wrapper - -RUN ./gradlew bootJar - -################################################## -# FINAL CONTAINER -################################################## - -FROM adoptopenjdk/openjdk12:jre-12.0.2_10-alpine - -USER root - -ARG VERSION - -WORKDIR /usr/src/app - -# copy jar, dev db, and dev resource files -COPY --from=gradleimage /home/gradle/source/build/libs/ga4gh-starter-kit-drs-${VERSION}.jar ga4gh-starter-kit-drs.jar -COPY --from=builder /usr/src/dependencies/ga4gh-starter-kit.dev.db ga4gh-starter-kit.dev.db -COPY src/test/resources/ src/test/resources/ - -ENTRYPOINT ["java", "-jar", "ga4gh-starter-kit-drs.jar"] +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/deprecated/starterkit/drs/app/DrsServer.java b/deprecated/starterkit/drs/app/DrsServer.java deleted file mode 100644 index 693fc00d..00000000 --- a/deprecated/starterkit/drs/app/DrsServer.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.ga4gh.starterkit.drs.app; - -import org.apache.commons.cli.Options; -import org.ga4gh.starterkit.common.util.webserver.ServerPropertySetter; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; - -/** - * Contains main method for running a standalone DRS deployment as a Spring Boot - * application - */ -@SpringBootApplication -@ComponentScan(basePackages = "org.ga4gh.starterkit.drs") -public class DrsServer { - - /** - * Run the DRS standalone server as a Spring Boot application. - * @param args command line arguments - */ - public static void main(String[] args) { - boolean setupSuccess = setup(args); - if (setupSuccess) { - try { - SpringApplication.run(DrsServer.class, args); - } catch (Exception ex) { - ex.printStackTrace(); - } - } else { - System.out.println("Application failed at initial setup phase, this is likely an error in the YAML config file. Exiting"); - } - } - - private static boolean setup(String[] args) { - Options options = new DrsServerSpringConfig().getCommandLineOptions(); - ServerPropertySetter setter = new ServerPropertySetter(); - return setter.setServerProperties(DrsServerYamlConfigContainer.class, args, options, "config"); - } -} diff --git a/deprecated/starterkit/drs/app/DrsServerConstants.java b/deprecated/starterkit/drs/app/DrsServerConstants.java deleted file mode 100644 index 02e52450..00000000 --- a/deprecated/starterkit/drs/app/DrsServerConstants.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.ga4gh.starterkit.drs.app; - -/** - * String constants for deployment config, generally Spring bean name/qualifier - * constants - */ -public class DrsServerConstants { - - /* Spring bean names - DRS config container */ - - /** - * Spring bean qualifier for an empty drs config container - */ - public static final String EMPTY_DRS_CONFIG_CONTAINER = "emptyDrsConfigContainer"; - - /** - * Spring bean qualifier for the drs config container containing all defaults - */ - public static final String DEFAULT_DRS_CONFIG_CONTAINER = "defaultDrsConfigContainer"; - - /** - * Spring bean qualifier for the drs config container containing user-loaded properties - */ - public static final String USER_DRS_CONFIG_CONTAINER = "userDrsConfigContainer"; - - /** - * Spring bean qualifier for the final drs config container containing merged - * properties from default and user-loaded (user-loaded properties override - * defaults) - */ - public static final String FINAL_DRS_CONFIG_CONTAINER = "finalDrsConfigContainer"; - - /* Spring bean scope */ - - /** - * Indicates Spring bean has 'prototype' lifecycle - */ - public static final String PROTOTYPE = "prototype"; -} diff --git a/deprecated/starterkit/drs/app/DrsServerSpringConfig.java b/deprecated/starterkit/drs/app/DrsServerSpringConfig.java deleted file mode 100644 index 789a52a1..00000000 --- a/deprecated/starterkit/drs/app/DrsServerSpringConfig.java +++ /dev/null @@ -1,336 +0,0 @@ -package org.ga4gh.starterkit.drs.app; - -import org.apache.catalina.connector.Connector; -import org.apache.commons.cli.*; -import org.ga4gh.starterkit.common.config.DatabaseProps; -import org.ga4gh.starterkit.common.config.ServerProps; -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.common.util.CliYamlConfigLoader; -import org.ga4gh.starterkit.common.util.DeepObjectMerger; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.ga4gh.starterkit.common.util.webserver.AdminEndpointsConnector; -import org.ga4gh.starterkit.common.util.webserver.AdminEndpointsFilter; -import org.ga4gh.starterkit.common.util.webserver.CorsFilterBuilder; -import org.ga4gh.starterkit.common.util.webserver.TomcatMultiConnectorServletWebServerFactoryCustomizer; -import org.ga4gh.starterkit.drs.config.DrsServiceProps; -import org.ga4gh.starterkit.drs.exception.DrsCustomExceptionHandling; -import org.ga4gh.starterkit.drs.model.*; -import org.ga4gh.starterkit.drs.utils.cache.AccessCache; -import org.ga4gh.starterkit.drs.utils.hibernate.DrsHibernateUtil; -import org.ga4gh.starterkit.drs.utils.passport.UserPassportMapVerifier; -import org.ga4gh.starterkit.drs.utils.requesthandler.AccessRequestHandler; -import org.ga4gh.starterkit.drs.utils.requesthandler.AuthInfoRequestHandler; -import org.ga4gh.starterkit.drs.utils.requesthandler.FileStreamRequestHandler; -import org.ga4gh.starterkit.drs.utils.requesthandler.ObjectRequestHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.web.server.WebServerFactoryCustomizer; -import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; -import org.springframework.web.context.annotation.RequestScope; -import org.springframework.web.filter.CorsFilter; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -/** - * Contains Spring bean definitions that are to be loaded for the DRS service - * under all deployment contexts (ie as part of both standalone and GA4GH - * multi-API service deployments) - * - * @see org.ga4gh.starterkit.drs.app.DrsStandaloneSpringConfig Spring config beans used only during standalone deployments - */ -@Configuration -@ConfigurationProperties -public class DrsServerSpringConfig { - - /* ****************************** - * TOMCAT SERVER - * ****************************** */ - - @Value("${server.admin.port:4501}") - private String serverAdminPort; - - @Bean - public WebServerFactoryCustomizer servletContainer() { - Connector[] additionalConnectors = AdminEndpointsConnector.additionalConnector(serverAdminPort); - ServerProperties serverProperties = new ServerProperties(); - return new TomcatMultiConnectorServletWebServerFactoryCustomizer(serverProperties, additionalConnectors); - } - - @Bean - public FilterRegistrationBean adminEndpointsFilter() { - return new FilterRegistrationBean(new AdminEndpointsFilter(Integer.valueOf(serverAdminPort))); - } - - @Bean - public DrsCustomExceptionHandling customExceptionHandling() { - return new DrsCustomExceptionHandling(); - } - - @Bean - public FilterRegistrationBean corsFilter( - @Autowired ServerProps serverProps - ) { - return new CorsFilterBuilder(serverProps).buildFilter(); - } - - /* ****************************** - * YAML CONFIG - * ****************************** */ - - /** - * Load command line options object, to enable parsing of program args - * @return valid command line options to be parsed - */ - @Bean - public Options getCommandLineOptions() { - final Options options = new Options(); - options.addOption("c", "config", true, "Path to DRS YAML config file"); - return options; - } - - /** - * Loads an empty DRS config container - * @return DRS config container with empty properties - */ - @Bean - @Scope(DrsServerConstants.PROTOTYPE) - @Qualifier(DrsServerConstants.EMPTY_DRS_CONFIG_CONTAINER) - public DrsServerYamlConfigContainer emptyDrsConfigContainer() { - return new DrsServerYamlConfigContainer(new DrsServerYamlConfig()); - } - - /** - * Loads a DRS config container singleton containing all default properties - * @return DRS config container containing defaults - */ - @Bean - @Qualifier(DrsServerConstants.DEFAULT_DRS_CONFIG_CONTAINER) - public DrsServerYamlConfigContainer defaultDrsConfigContainer() { - return new DrsServerYamlConfigContainer(new DrsServerYamlConfig()); - } - - public static boolean validateArguments(ApplicationArguments args, String optionName) { - try { - Options options = new Options(); - options.addOption(Option.builder("c") - .longOpt(optionName) - .hasArg() - .desc("Path to configuration file") - .build()); - - CommandLineParser parser = new DefaultParser(); - parser.parse(options, args.getSourceArgs()); - return true; - } catch (ParseException e) { - System.out.println("ERROR: Invalid arguments: " + e.getMessage()); - return false; - } - } - - /** - * Loads a DRS config container singleton containing user-specified properties (via config file) - * @param args command line args - * @param options valid set of command line options to be parsed - * @param drsConfigContainer empty DRS config container - * @return DRS config container singleton containing user-specified properties - */ - @Bean - @Qualifier(DrsServerConstants.USER_DRS_CONFIG_CONTAINER) - public DrsServerYamlConfigContainer runtimeDrsConfigContainer( - @Autowired ApplicationArguments args, - @Autowired() Options options, - @Qualifier(DrsServerConstants.EMPTY_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer drsConfigContainer - ) { - if (!validateArguments(args, "config")) { - System.exit(1); // Exit if validation fails - } - - DrsServerYamlConfigContainer userConfigContainer = CliYamlConfigLoader.load(DrsServerYamlConfigContainer.class, args, options, "config"); - if (userConfigContainer != null) { - return userConfigContainer; - } - return drsConfigContainer; - } - - /** - * Loads the final DRS config container singleton containing merged properties - * between default and user-specified - * @param defaultContainer contains default properties - * @param userContainer contains user-specified properties - * @return contains merged properties - */ - @Bean - @Qualifier(DrsServerConstants.FINAL_DRS_CONFIG_CONTAINER) - public DrsServerYamlConfigContainer mergedDrsConfigContainer( - @Qualifier(DrsServerConstants.DEFAULT_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer defaultContainer, - @Qualifier(DrsServerConstants.USER_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer userContainer - ) { - DeepObjectMerger merger = new DeepObjectMerger(); - merger.merge(userContainer, defaultContainer); - return defaultContainer; - } - - /** - * Retrieve server props object from merged DRS config container - * @param drsConfigContainer merged DRS config container - * @return merged server props - */ - @Bean - public ServerProps getServerProps( - @Qualifier(DrsServerConstants.FINAL_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer drsConfigContainer - ) { - return drsConfigContainer.getDrs().getServerProps(); - } - - /** - * Retrieve database props object from merged DRS config container - * @param annotatedClasses list of hibernate entity classes to be managed by the DRS hibernate util - * @param drsConfigContainer merged DRS config container - * @return merged database props - */ - @Bean - public DatabaseProps getDatabaseProps( - @Autowired List>> annotatedClasses, - @Qualifier(DrsServerConstants.FINAL_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer drsConfigContainer - ) { - return drsConfigContainer.getDrs().getDatabaseProps(); - } - - /** - * Retrieve DRS service info object from merged DRS config container - * @param drsConfigContainer merged DRS config container - * @return merged DRS service info - */ - @Bean - public DrsServiceInfo getServiceInfo( - @Qualifier(DrsServerConstants.FINAL_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer drsConfigContainer - ) { - return drsConfigContainer.getDrs().getServiceInfo(); - } - - /** - * Retrieve DRS service properties from merged DRS config container - * @param drsConfigContainer merged DRS config container - * @return merged DRS service properties - */ - @Bean - public DrsServiceProps getDrsServiceProps( - @Qualifier(DrsServerConstants.FINAL_DRS_CONFIG_CONTAINER) DrsServerYamlConfigContainer drsConfigContainer - ) { - return drsConfigContainer.getDrs().getDrsServiceProps(); - } - - /* ****************************** - * LOGGING - * ****************************** */ - - @Bean - public LoggingUtil loggingUtil() { - return new LoggingUtil(); - } - - /* ****************************** - * HIBERNATE CONFIG - * ****************************** */ - - /** - * List of hibernate entity classes to be managed by the Drs hibernate util - * @return list of DRS-related managed entity classes - */ - @Bean - public List>> getAnnotatedClasses() { - List>> annotatedClasses = new ArrayList<>(); - annotatedClasses.add(DrsObject.class); - annotatedClasses.add(Checksum.class); - annotatedClasses.add(FileAccessObject.class); - annotatedClasses.add(AwsS3AccessObject.class); - annotatedClasses.add(PassportBroker.class); - annotatedClasses.add(PassportVisa.class); - return annotatedClasses; - } - - /** - * Loads/retrieves the hibernate util singleton providing access to DRS-related database tables - * @param annotatedClasses list of DRS-related entities to be managed - * @param databaseProps database properties from configuration - * @return loaded hibernate util singleton managing DRS entities - */ - @Bean - public DrsHibernateUtil getDrsHibernateUtil( - @Autowired List>> annotatedClasses, - @Autowired DatabaseProps databaseProps - ) { - DrsHibernateUtil hibernateUtil = new DrsHibernateUtil(); - hibernateUtil.setAnnotatedClasses(annotatedClasses); - hibernateUtil.setDatabaseProps(databaseProps); - return hibernateUtil; - } - - /* ****************************** - * REQUEST HANDLER - * ****************************** */ - - /** - * Get new request handler facilitating access to a DRSObject - * @return drs object request handler - */ - @Bean - @Scope(DrsServerConstants.PROTOTYPE) - public ObjectRequestHandler objectRequestHandler() { - return new ObjectRequestHandler(); - } - - /** - * Get new request handler facilitating the 'access' endpoint, i.e. provides - * an AccessURL for a given object_id and access_id - * @return access URL request handler - */ - @Bean - @RequestScope - public AccessRequestHandler accessRequestHandler() { - return new AccessRequestHandler(); - } - - @Bean - @RequestScope - public AuthInfoRequestHandler authInfoRequestHandler() { - return new AuthInfoRequestHandler(); - } - - /** - * Get new request handler facilitating streaming of a local file over http(s) - * @return streaming request handler - */ - @Bean - @RequestScope - public FileStreamRequestHandler fileStreamRequestHandler() { - return new FileStreamRequestHandler(); - } - - /* ****************************** - * OTHER UTILS - * ****************************** */ - - /** - * Get cache singleton, storing object_id and access_id mappings - * @return object_id, access_id cache - */ - @Bean - public AccessCache accessCache() { - return new AccessCache(); - } - - @Bean - public UserPassportMapVerifier userPAssportMapVerifier() { - return new UserPassportMapVerifier(); - } -} diff --git a/deprecated/starterkit/drs/app/DrsServerYamlConfig.java b/deprecated/starterkit/drs/app/DrsServerYamlConfig.java deleted file mode 100644 index 74b827b7..00000000 --- a/deprecated/starterkit/drs/app/DrsServerYamlConfig.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.ga4gh.starterkit.drs.app; - -import org.ga4gh.starterkit.common.config.DatabaseProps; -import org.ga4gh.starterkit.common.config.ServerProps; -import org.ga4gh.starterkit.drs.config.DrsDatabaseProps; -import org.ga4gh.starterkit.drs.config.DrsServiceProps; -import org.ga4gh.starterkit.drs.model.DrsServiceInfo; - -/** - * Contains multiple configuration objects affecting application behavior. - * To be deserialized/loaded as part of a YAML config file specified on the - * command line - */ -public class DrsServerYamlConfig { - - private ServerProps serverProps; - private DrsDatabaseProps databaseProps; - private DrsServiceInfo serviceInfo; - private DrsServiceProps drsServiceProps; - - /** - * Instantiates a new DrsStandaloneYamlConfig object with default properties - */ - public DrsServerYamlConfig() { - serverProps = new ServerProps(); - databaseProps = new DrsDatabaseProps(); - serviceInfo = new DrsServiceInfo(); - drsServiceProps = new DrsServiceProps(); - } - - /** - * Assign serverProps - * @param serverProps ServerProps object - */ - public void setServerProps(ServerProps serverProps) { - this.serverProps = serverProps; - } - - /** - * Retrieve server props - * @return ServerProps object - */ - public ServerProps getServerProps() { - return serverProps; - } - - /** - * Assign databaseProps - * @param databaseProps DatabaseProps object - */ - public void setDatabaseProps(DrsDatabaseProps databaseProps) { - this.databaseProps = databaseProps; - } - - /** - * Retrieve databaseProps - * @return DatabaseProps object - */ - public DatabaseProps getDatabaseProps() { - return databaseProps; - } - - /** - * Assign serviceInfo - * @param serviceInfo DrsServiceInfo object - */ - public void setServiceInfo(DrsServiceInfo serviceInfo) { - this.serviceInfo = serviceInfo; - } - - /** - * Retrieve serviceInfo - * @return DrsServiceInfo object - */ - public DrsServiceInfo getServiceInfo() { - return serviceInfo; - } - - /** - * Assign drsServiceProps - * @param drsServiceProps DrsServiceProps object - */ - public void setDrsServiceProps(DrsServiceProps drsServiceProps) { - this.drsServiceProps = drsServiceProps; - } - - /** - * Retrieve drsServiceProps - * @return DrsServiceProps object - */ - public DrsServiceProps getDrsServiceProps() { - return drsServiceProps; - } -} diff --git a/deprecated/starterkit/drs/app/DrsServerYamlConfigContainer.java b/deprecated/starterkit/drs/app/DrsServerYamlConfigContainer.java deleted file mode 100644 index 12c5c70f..00000000 --- a/deprecated/starterkit/drs/app/DrsServerYamlConfigContainer.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.ga4gh.starterkit.drs.app; - -import org.ga4gh.starterkit.common.config.ContainsServerProps; -import org.ga4gh.starterkit.common.config.ServerProps; - -/** - * Top-level configuration container object for standalone deployments. To - * be deserialized/loaded as part of a YAML config file specified on the command - * line. - */ -public class DrsServerYamlConfigContainer implements ContainsServerProps { - - /** - * Nested configuration object - */ - private DrsServerYamlConfig drs; - - /** - * Instantiates a new DrsStandaloneYamlConfigContainer object with default properties - */ - public DrsServerYamlConfigContainer() { - drs = new DrsServerYamlConfig(); - } - - /** - * Instantiates a new DrsStandaloneYamlConfigContainer with a preconfigured DrsStandaloneYamlConfig object - * @param drs preconfigured DrsStandaloneYamlConfig object - */ - public DrsServerYamlConfigContainer(DrsServerYamlConfig drs) { - this.drs = drs; - } - - /** - * Retrieve server props through the nested inner config object - * @return server props - */ - public ServerProps getServerProps() { - return getDrs().getServerProps(); - } - - /** - * Assign drs - * @param drs DrsStandaloneYamlConfig object - */ - public void setDrs(DrsServerYamlConfig drs) { - this.drs = drs; - } - - /** - * Retrieve drs - * @return DrsStandaloneYamlConfig object - */ - public DrsServerYamlConfig getDrs() { - return drs; - } -} diff --git a/deprecated/starterkit/drs/app/package-info.java b/deprecated/starterkit/drs/app/package-info.java deleted file mode 100644 index 483de2b8..00000000 --- a/deprecated/starterkit/drs/app/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Enables running the Starter Kit DRS as a standalone web service - *

- * This package contains the classes necessary to deploy the Starter Kit DRS - * as a standalone web service. Contains the main method, classes for loading - * configurations, and Spring bean configuration - *

- * - * @since 0.1.4 - * @version 0.1.4 - */ -package org.ga4gh.starterkit.drs.app; \ No newline at end of file diff --git a/deprecated/starterkit/drs/config/DatabaseType.java b/deprecated/starterkit/drs/config/DatabaseType.java deleted file mode 100644 index 792722e4..00000000 --- a/deprecated/starterkit/drs/config/DatabaseType.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.ga4gh.starterkit.drs.config; - -/** - * @author dashrath - */ -public enum DatabaseType { - mysql, - postgres, - sqlite -} diff --git a/deprecated/starterkit/drs/config/DrsDatabaseProps.java b/deprecated/starterkit/drs/config/DrsDatabaseProps.java deleted file mode 100644 index ad13ca36..00000000 --- a/deprecated/starterkit/drs/config/DrsDatabaseProps.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.ga4gh.starterkit.drs.config; - -import org.ga4gh.starterkit.common.config.DatabaseProps; - -import java.util.Properties; - -import static org.ga4gh.starterkit.common.constant.DatabasePropsConstants.*; - -/** - * @author dashrath - */ -public class DrsDatabaseProps extends DatabaseProps { - - private String url; - private String username; - private String password; - private String poolSize; - private String showSQL; - - // constants for mysql db type - public static final String MYSQL_DRIVER_CLASS = "com.mysql.cj.jdbc.Driver"; - public static final String MYSQL_DIALECT = "org.hibernate.dialect.MySQL8Dialect"; - - public Properties getAllProperties() { - Properties props = new Properties(); - - // set common properties across any db type: url, username, password, - // pool_size, show_sql, - props.setProperty("hibernate.connection.url", getUrl()); - - if (!getUsername().equals("")) { - props.setProperty("hibernate.connection.username", getUsername()); - } - - if (!getPassword().equals("")) { - props.setProperty("hibernate.connection.password", getPassword()); - } - - props.setProperty("hibernate.connection.pool_size", getPoolSize()); - props.setProperty("hibernate.show_sql", getShowSQL()); - - // set hardcoded properties: current_session_context_class - props.setProperty("hibernate.current_session_context_class", DEFAULT_CURRENT_SESSION_CONTEXT_CLASS); - - // infer database type (ie sqlite or postgresql) from the db connection url - DatabaseType dbtype = getDatabaseTypeFromUrl(getUrl()); - - switch(dbtype) { - case mysql: - assignMySQLProperties(props); - break; - - case postgres: - assignPostgresProperties(props); - break; - - case sqlite: - assignSqliteProperties(props); - break; - } - - return props; - } - - private DatabaseType getDatabaseTypeFromUrl(String url) { - - if (url.startsWith("jdbc:sqlite")) { - return DatabaseType.sqlite; - } - - if (url.startsWith("jdbc:postgresql")) { - return DatabaseType.postgres; - } - - if (url.startsWith("jdbc:mysql")) { - return DatabaseType.mysql; - } - - throw new IllegalArgumentException("Invalid JDBC URL: MUST be a valid 'sqlite', 'postgresql', or 'mysql' JDBC URL"); - } - - private void assignSqliteProperties(Properties props) { - props.setProperty("hibernate.connection.driver_class", SQLITE_DRIVER_CLASS); - props.setProperty("hibernate.dialect", SQLITE_DIALECT); - props.setProperty("hibernate.connection.date_class", SQLITE_DATE_CLASS); - } - - private void assignPostgresProperties(Properties props) { - props.setProperty("hibernate.connection.driver_class", POSTGRES_DRIVER_CLASS); - props.setProperty("hibernate.dialect", POSTGRES_DIALECT); - } - - private void assignMySQLProperties(Properties props) { - props.setProperty("hibernate.connection.driver_class", MYSQL_DRIVER_CLASS); - props.setProperty("hibernate.dialect", MYSQL_DIALECT); - } -} diff --git a/deprecated/starterkit/drs/config/DrsServiceProps.java b/deprecated/starterkit/drs/config/DrsServiceProps.java deleted file mode 100644 index 060a034c..00000000 --- a/deprecated/starterkit/drs/config/DrsServiceProps.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.ga4gh.starterkit.drs.config; - -/** - * Configuration properties modifying application behaviour that are unique - * only to DRS. To be deserialized/loaded from YAML config file - */ -public class DrsServiceProps { - - /** - * Indicates whether the DRS service should provide file URLs of DRSObject - * file location back to the client. If true, assumes that client has - * access to the same filesystem as the service (e.g. HPC environment). - * Applies only to 'file' based objects (ie not https, s3, etc.) - */ - private boolean serveFileURLForFileObjects; - - /** - * Indicates whether the DRS service should provide the streaming endpoint - * URL to the client, for files that the server can access but the client - * cannot. If true, assumes that client cannot access the file by its path. - * Applies only to 'file' based objects (ie not https, s3, etc.) - */ - private boolean serveStreamURLForFileObjects; - - /** - * Instantiates a new DrsServiceProps object with all defaults - */ - public DrsServiceProps() { - setAllDefaults(); - } - - /** - * Assign boolean, indicating whether to serve file paths - * @param serveFileURLForFileObjects boolean indicator - */ - public void setServeFileURLForFileObjects(boolean serveFileURLForFileObjects) { - this.serveFileURLForFileObjects = serveFileURLForFileObjects; - } - - /** - * Retrieve boolean indicating whether to serve file paths - * @return boolean indicator - */ - public boolean getServeFileURLForFileObjects() { - return serveFileURLForFileObjects; - } - - /** - * Assign boolean, indicating whether to serve files via stream endpoint - * @param serveStreamURLForFileObjects boolean indicator - */ - public void setServeStreamURLForFileObjects(boolean serveStreamURLForFileObjects) { - this.serveStreamURLForFileObjects = serveStreamURLForFileObjects; - } - - /** - * Retrieve boolean, indicating whether to serve files via stream endpoint - * @return boolean indicator - */ - public boolean getServeStreamURLForFileObjects() { - return serveStreamURLForFileObjects; - } - - /** - * Initialize DRS service props with defaults - */ - private void setAllDefaults() { - serveFileURLForFileObjects = true; - serveStreamURLForFileObjects = false; - } -} diff --git a/deprecated/starterkit/drs/config/package-info.java b/deprecated/starterkit/drs/config/package-info.java deleted file mode 100644 index 6f50f760..00000000 --- a/deprecated/starterkit/drs/config/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Defines configuration classes modifying application behavior that are unique - * only to DRS. Generally deserialized/loaded from YAML config file - * - * @since 0.1.4 - * @version 0.1.4 - */ -package org.ga4gh.starterkit.drs.config; \ No newline at end of file diff --git a/deprecated/starterkit/drs/constant/DrsApiConstants.java b/deprecated/starterkit/drs/constant/DrsApiConstants.java deleted file mode 100644 index 187fe678..00000000 --- a/deprecated/starterkit/drs/constant/DrsApiConstants.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.ga4gh.starterkit.drs.constant; - -import static org.ga4gh.starterkit.common.constant.StarterKitConstants.ADMIN; -import static org.ga4gh.starterkit.common.constant.StarterKitConstants.GA4GH; -import static org.ga4gh.starterkit.common.constant.StarterKitConstants.DRS; -import static org.ga4gh.starterkit.common.constant.StarterKitConstants.V1; - -/** - * DRS API URL path/routing constants - */ -public class DrsApiConstants { - - /** - * Common REST API route to most (if not all) DRS-related controller functions - */ - public static final String DRS_API_V1 = "/" + GA4GH + "/" + DRS + "/" + V1; - - /** - * Common REST API route to most (if not all) off-spec, administrative controller - * functions for modifying DRS-related entities - */ - public static final String ADMIN_DRS_API_V1 = "/" + ADMIN + DRS_API_V1; -} diff --git a/deprecated/starterkit/drs/constant/DrsServiceInfoDefaults.java b/deprecated/starterkit/drs/constant/DrsServiceInfoDefaults.java deleted file mode 100644 index a5b7315a..00000000 --- a/deprecated/starterkit/drs/constant/DrsServiceInfoDefaults.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.ga4gh.starterkit.drs.constant; - -import java.time.LocalDateTime; - -import org.ga4gh.starterkit.common.constant.DateTimeConstants; - -/** - * Default values for the DRS service info response - */ -public class DrsServiceInfoDefaults { - - /** - * Default service id - */ - public static final String ID = "org.ga4gh.starterkit.drs"; - - /** - * Default service name - */ - public static final String NAME = "GA4GH Starter Kit DRS Service"; - - /** - * Default service description - */ - public static final String DESCRIPTION = "An open source, community-driven" - + " implementation of the GA4GH Data Repository Service (DRS)" - + " API specification."; - - /** - * Default service contact URL - */ - public static final String CONTACT_URL = "mailto:info@ga4gh.org"; - - /** - * Default service documentation URL - */ - public static final String DOCUMENTATION_URL = "https://github.com/ga4gh/ga4gh-starter-kit-drs"; - - /** - * Default service creation/launch time - */ - public static final LocalDateTime CREATED_AT = LocalDateTime.parse("2020-01-15T12:00:00Z", DateTimeConstants.DATE_FORMATTER); - - /** - * Default service last updated time - */ - public static final LocalDateTime UPDATED_AT = LocalDateTime.parse("2020-01-15T12:00:00Z", DateTimeConstants.DATE_FORMATTER);; - - /** - * Default service environment - */ - public static final String ENVIRONMENT = "test"; - - /** - * Default service version - */ - public static final String VERSION = "0.3.2"; - - /** - * Default service organization name - */ - public static final String ORGANIZATION_NAME = "Global Alliance for Genomics and Health"; - - /** - * Default service organization URL - */ - public static final String ORGANIZATION_URL = "https://ga4gh.org"; - - /** - * Default service type group - */ - public static final String SERVICE_TYPE_GROUP = "org.ga4gh"; - - /** - * Default service type artifact - */ - public static final String SERVICE_TYPE_ARTIFACT = "drs"; - - /** - * Default service type version - */ - public static final String SERVICE_TYPE_VERSION = "1.3.0experimental"; -} \ No newline at end of file diff --git a/deprecated/starterkit/drs/constant/package-info.java b/deprecated/starterkit/drs/constant/package-info.java deleted file mode 100644 index 56bdac2f..00000000 --- a/deprecated/starterkit/drs/constant/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Contains program-wide constants to be used by various components of the DRS API - * - * @since 0.1.4 - * @version 0.1.4 - */ -package org.ga4gh.starterkit.drs.constant; diff --git a/deprecated/starterkit/drs/controller/DrsAdmin.java b/deprecated/starterkit/drs/controller/DrsAdmin.java deleted file mode 100644 index 17ff1c83..00000000 --- a/deprecated/starterkit/drs/controller/DrsAdmin.java +++ /dev/null @@ -1,206 +0,0 @@ -package org.ga4gh.starterkit.drs.controller; - -import com.fasterxml.jackson.annotation.JsonView; -import org.ga4gh.starterkit.common.exception.BadRequestException; -import org.ga4gh.starterkit.common.exception.ConflictException; -import org.ga4gh.starterkit.common.exception.ResourceNotFoundException; -import org.ga4gh.starterkit.common.hibernate.exception.EntityDoesntExistException; -import org.ga4gh.starterkit.common.hibernate.exception.EntityExistsException; -import org.ga4gh.starterkit.common.hibernate.exception.EntityMismatchException; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.ga4gh.starterkit.drs.model.DrsObject; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.ga4gh.starterkit.drs.utils.hibernate.DrsHibernateUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -import static org.ga4gh.starterkit.drs.constant.DrsApiConstants.ADMIN_DRS_API_V1; - -/** - * Controller functions for the administrative API, create and modify DRS-related - * entities - */ -@RestController -@RequestMapping(ADMIN_DRS_API_V1 + "/objects") // /admin/ga4gh/drs/v1 -public class DrsAdmin { - - @Autowired - private DrsHibernateUtil hibernateUtil; - - @Autowired - private LoggingUtil loggingUtil; - - // Non-standard endpoints - admin views - - /** - * Display DRSObject list - * @return DRSObject list - */ - @GetMapping - @JsonView(SerializeView.Always.class) - public List indexDrsObjects() { - loggingUtil.debug("Admin API request: DrsObject list"); - return hibernateUtil.getEntityList(DrsObject.class); - } - - /** - * Display all data for a single DRSObject - * @param id identifier for DRSObject of interest - * @return metadata for DRSObject - */ - @GetMapping(path = "/{object_id:.+}") - @JsonView(SerializeView.Admin.class) - public DrsObject showDrsObject( - @PathVariable(name = "object_id") String id - ) { - loggingUtil.debug("Admin API request: DrsObject with id '" + id + "'"); - DrsObject drsObject = hibernateUtil.loadDrsObject(id, false); - if (drsObject == null) { - String exceptionMessage = "No DrsObject found by id: " + id; - loggingUtil.error("Exception occurred: " + exceptionMessage); - throw new ResourceNotFoundException(exceptionMessage); - } - return getAdminFormattedDrsObject(id); - } - - // Non-standard endpoints - write operations - - /** - * Create a new DRSObject in the database - * @param drsObject new, non persistent DRSObject - * @return persistent DRSObject saved with the requested attributes - */ - @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) - @JsonView(SerializeView.Admin.class) - public DrsObject createDrsObject( - @RequestBody DrsObject drsObject - ) { - loggingUtil.debug("Admin API request: create new DrsObject"); - loggingUtil.trace(drsObject.toString()); - try { - hibernateUtil.createEntityObject(DrsObject.class, drsObject); - return getAdminFormattedDrsObject(drsObject.getId()); - } catch (EntityExistsException ex) { - loggingUtil.error("Exception occurred: Entity exists exception" + ex.getMessage()); - throw new ConflictException(ex.getMessage()); - } - } - - /** - * Update an existing DRSObject with new properties - * @param id identifier of DRSObject to be modified - * @param drsObject new DRSObject properties - * @return persistent DRSObject with overwritten attributes according to request body - */ - @PutMapping(path = "/{object_id:.+}") - public DrsObject updateDrsObject( - @PathVariable(name = "object_id") String id, - @RequestBody DrsObject drsObject - ) { - loggingUtil.debug("Admin API request: update DrsObject with id '" + id + "'"); - loggingUtil.trace(drsObject.toString()); - try { - hibernateUtil.updateEntityObject(DrsObject.class, id, drsObject); - return getAdminFormattedDrsObject(id); - } catch (EntityMismatchException ex) { - loggingUtil.error("Exception occurred: Entity mismatch exception" + ex.getMessage()); - throw new BadRequestException(ex.getMessage()); - } catch (EntityDoesntExistException ex) { - loggingUtil.error("Exception occurred: Entity mismatch exception" + ex.getMessage()); - throw new ConflictException(ex.getMessage()); - } - } - - /** - * Delete an existing DRSObject - * @param id identifier of DRSObject to be deleted - * @return empty response body, indicating successful deletion - */ - @DeleteMapping(path = "/{object_id:.+}") - public DrsObject deleteDrsObject( - @PathVariable(name = "object_id") String id - ) { - loggingUtil.debug("Admin API request: delete DrsObject with id '" + id + "'"); - try { - hibernateUtil.deleteEntityObject(DrsObject.class, id); - return hibernateUtil.readEntityObject(DrsObject.class, id, false); - } catch (EntityDoesntExistException ex) { - loggingUtil.error("Exception occurred: entity doesnt exist exception" + ex.getMessage()); - throw new ConflictException(ex.getMessage()); - } catch (EntityExistsException ex) { - loggingUtil.error("Exception occurred: entity exists exception" + ex.getMessage()); - throw new ConflictException(ex.getMessage()); - } - } - - /** - * High-level function to load a DRSObject with all necessary properties - * to get an administrative view, while avoiding infinite recursive - * deserialization problem - * @param id identifier of DRSObject to be loaded - * @return administrative view of DRSObject - */ - private DrsObject getAdminFormattedDrsObject(String id) { - DrsObject drsObject = hibernateUtil.loadDrsObject(id, false); - breakInterminableFetchForChildrenAndParents(drsObject); - return drsObject; - } - - /** - * For a given DRSObject, avoid infinite recursive serialization by setting - * certain attributes of its parents and children to null - * @param drsObject DRSObject to be loaded - */ - private void breakInterminableFetchForChildrenAndParents(DrsObject drsObject) { - for (DrsObject childDrsObject: drsObject.getDrsObjectChildren()) { - // each of the DRSObject's children have certain attributes set to - // null to avoid infinite serialization - breakInterminableFetch(childDrsObject); - } - for (DrsObject parentDrsObject: drsObject.getDrsObjectParents()) { - // each of the DRSObject's parents have certain attributes set to - // null to avoid infinite serialization - breakInterminableFetch(parentDrsObject); - } - } - - /** - * Assign certain attributes to null to avoid infinite recursive serialization. - * Only for administrative views of an object, does not affect the persistent - * state of an object - * @param drsObject DRSObject to be modified - */ - private void breakInterminableFetch(DrsObject drsObject) { - drsObject.setAliases(null); - drsObject.setChecksums(null); - drsObject.setFileAccessObjects(null); - drsObject.setAwsS3AccessObjects(null); - drsObject.setDrsObjectChildren(null); - drsObject.setDrsObjectParents(null); - drsObject.setPassportVisas(null); - } - - /** - * Loads multiple DRS Objects into database - * @param file - * @return persistent DRSObject saved with the requested attributes - */ - @PostMapping(path = "/bulkInsert") - @JsonView(SerializeView.Admin.class) - public ResponseEntity bulkInsert(@RequestParam("file") MultipartFile file) { - loggingUtil.debug("Admin API request: bulk insert DRS objects"); - try { - hibernateUtil.insertBulkDrsObjects(file); - return new ResponseEntity<>("File uploaded and data inserted successfully", HttpStatus.OK); - } catch (Exception e) { - loggingUtil.error("Error processing the file: " + e.getMessage()+ e); - return new ResponseEntity<>("Error processing the file: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } - } -} diff --git a/deprecated/starterkit/drs/controller/DrsServiceInfo.java b/deprecated/starterkit/drs/controller/DrsServiceInfo.java deleted file mode 100644 index 736736e3..00000000 --- a/deprecated/starterkit/drs/controller/DrsServiceInfo.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.ga4gh.starterkit.drs.controller; - -import static org.ga4gh.starterkit.drs.constant.DrsApiConstants.DRS_API_V1; - -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Service info controller, displays generic and DRS-specific service info - */ -@RestController -@RequestMapping(DRS_API_V1 + "/service-info") -public class DrsServiceInfo { - - @Autowired - private org.ga4gh.starterkit.drs.model.DrsServiceInfo drsServiceInfo; - - @Autowired - private LoggingUtil loggingUtil; - - /** - * Display service info - * @return DRS service info - */ - @GetMapping //(produces = MediaType.APPLICATION_JSON_VALUE) - public org.ga4gh.starterkit.drs.model.DrsServiceInfo getServiceInfo() { - loggingUtil.debug("Public API request: service info"); - loggingUtil.trace(drsServiceInfo.toString()); - return drsServiceInfo; - } -} diff --git a/deprecated/starterkit/drs/controller/Objects.java b/deprecated/starterkit/drs/controller/Objects.java deleted file mode 100644 index 1063420b..00000000 --- a/deprecated/starterkit/drs/controller/Objects.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.ga4gh.starterkit.drs.controller; - -import static org.ga4gh.starterkit.drs.constant.DrsApiConstants.DRS_API_V1; - -import java.util.ArrayList; -import java.util.List; -import org.ga4gh.starterkit.common.exception.CustomException; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.ga4gh.starterkit.drs.model.AccessURL; -import org.ga4gh.starterkit.drs.model.AuthInfo; -import org.ga4gh.starterkit.drs.model.BulkAccessRequest; -import org.ga4gh.starterkit.drs.model.BulkAuthInfoRequest; -import org.ga4gh.starterkit.drs.model.BulkAuthInfoResponse; -import org.ga4gh.starterkit.drs.model.BulkObjectAccessId; -import org.ga4gh.starterkit.drs.model.BulkRequest; -import org.ga4gh.starterkit.drs.model.BulkResponse; -import org.ga4gh.starterkit.drs.model.DrsObject; -import org.ga4gh.starterkit.drs.model.PostSingleObjectRequestBody; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.ga4gh.starterkit.drs.utils.passport.UserPassportMap; -import org.ga4gh.starterkit.drs.utils.passport.UserPassportMapVerifier; -import org.ga4gh.starterkit.drs.utils.requesthandler.AccessRequestHandler; -import org.ga4gh.starterkit.drs.utils.requesthandler.AuthInfoRequestHandler; -import org.ga4gh.starterkit.drs.utils.requesthandler.ObjectRequestHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import javax.annotation.Resource; -import com.fasterxml.jackson.annotation.JsonView; - -/** - * Controller functions for accessing DRSObjects according to the DRS specification - */ -@RestController -@RequestMapping(DRS_API_V1 + "/objects") -public class Objects implements ApplicationContextAware { - - @Resource(name = "objectRequestHandler") - private ObjectRequestHandler objectRequestHandler; - - @Resource(name = "accessRequestHandler") - private AccessRequestHandler accessRequestHandler; - - @Resource(name = "authInfoRequestHandler") - private AuthInfoRequestHandler authInfoRequestHandler; - - @Autowired - private LoggingUtil loggingUtil; - - @Autowired - private UserPassportMapVerifier passportVerifier; - - private ApplicationContext context; - - // Standard endpoints - - /** - * Show information about a DRS object - * @param objectId identifier of DRSObject of interest - * @param expand if true, display recursive bundling under 'contents' property - * @return DRSObject by the requested id - */ - @GetMapping(path = "/{object_id:.+}") - @JsonView(SerializeView.Public.class) - public DrsObject getObjectById( - @PathVariable(name = "object_id") String objectId, - @RequestParam(name = "expand", required = false) boolean expand - ) { - loggingUtil.debug("Public API request: DrsObject with id '" + objectId + "', expand=" + expand); - return objectRequestHandler.prepare(objectId, expand, null).handleRequest(); - } - - @PostMapping(path = "/{object_id:.+}") - @JsonView(SerializeView.Public.class) - public DrsObject getObjectByIdViaPost( - @PathVariable(name = "object_id") String objectId, - @RequestBody PostSingleObjectRequestBody requestBody - ) { - UserPassportMap userPassportMap = null; - if (requestBody.getPassports() != null) { - userPassportMap = new UserPassportMap(requestBody.getPassports()); - passportVerifier.verifyAll(userPassportMap); - } - return objectRequestHandler.prepare(objectId, requestBody.isExpand(), userPassportMap).handleRequest(); - } - - @RequestMapping(value = "/{object_id:.+}", method = RequestMethod.OPTIONS) - @JsonView(SerializeView.Public.class) - public AuthInfo singleObjectAuthInfo( - @PathVariable(name = "object_id") String objectId - ) { - return authInfoRequestHandler.prepare(objectId).handleRequest(); - } - - /** - * Get an access URL for fetching the DRS Object's file bytes - * @param objectId DRSObject identifier - * @param accessId access identifier - * @return a DRS-spec AccessURL indicating file bytes location - */ - @GetMapping(path = "/{object_id:.+}/access/{access_id:.+}") - public AccessURL getAccessURLById( - @PathVariable(name = "object_id") String objectId, - @PathVariable(name = "access_id") String accessId - ) { - loggingUtil.debug("Public API request: AccessURL for DRS id '" + objectId + "', access id '" + accessId + "'"); - return accessRequestHandler.prepare(objectId, accessId).handleRequest(); - } - - @PostMapping - @JsonView(SerializeView.Public.class) - public BulkResponse getBulkObjects( - @RequestBody BulkRequest bulkRequest - ) { - // parse user passport - UserPassportMap userPassportMap = null; - if (bulkRequest.getPassports() != null) { - userPassportMap = new UserPassportMap(bulkRequest.getPassports()); - passportVerifier.verifyAll(userPassportMap); - } - - BulkResponse bulkResponse = new BulkResponse(); - int requested = 0; - int resolved = 0; - int unresolved = 0; - - for (String drsObjectId : bulkRequest.getSelection()) { - requested++; - try { - ObjectRequestHandler handler = context.getBean(ObjectRequestHandler.class); - DrsObject drsObject = handler.prepare(drsObjectId, false, userPassportMap).handleRequest(); - bulkResponse.getResolvedDrsObject().add(drsObject); - resolved++; - } catch (CustomException ex) { - int httpStatus = ex.getClass().getAnnotation(ResponseStatus.class).value().value(); - bulkResponse.getUnresolvedDrsObject().put(drsObjectId, httpStatus); - unresolved++; - } - } - bulkResponse.getSummary().setRequested(requested); - bulkResponse.getSummary().setResolved(resolved); - bulkResponse.getSummary().setUnresolved(unresolved); - - return bulkResponse; - } - - @RequestMapping(method = RequestMethod.OPTIONS) - @JsonView(SerializeView.Public.class) - public BulkAuthInfoResponse getBulkAuthInfo( - @RequestBody BulkAuthInfoRequest request - ) { - BulkAuthInfoResponse response = new BulkAuthInfoResponse(); - int requested = 0; - int resolved = 0; - int unresolved = 0; - - for (String drsObjectId : request.getSelection()) { - requested++; - try { - AuthInfoRequestHandler handler = context.getBean(AuthInfoRequestHandler.class); - AuthInfo authInfo = handler.prepare(drsObjectId).handleRequest(); - response.getResolvedDrsObjectAuthInfo().put(drsObjectId, authInfo); - resolved++; - } catch (CustomException ex) { - int httpStatus = ex.getClass().getAnnotation(ResponseStatus.class).value().value(); - response.getUnresolvedDrsObjectAuthInfo().put(drsObjectId, httpStatus); - unresolved++; - } - } - response.getSummary().setRequested(requested); - response.getSummary().setResolved(resolved); - response.getSummary().setUnresolved(unresolved); - return response; - } - - @PostMapping(path = "/access") - @JsonView(SerializeView.Public.class) - public List getBulkAccessURLs( - @RequestBody BulkAccessRequest bulkAccessRequest - ) { - List accessURLs = new ArrayList<>(); - for (BulkObjectAccessId idPair : bulkAccessRequest.getSelection()) { - try { - AccessRequestHandler handler = context.getBean(AccessRequestHandler.class); - AccessURL accessURL = handler.prepare(idPair.getObjectId(), idPair.getAccessId()).handleRequest(); - accessURLs.add(accessURL); - } catch (CustomException ex) { - loggingUtil.error("Exception occurred: " + ex.getMessage()); - } - } - - return accessURLs; - } - - public void setApplicationContext(ApplicationContext context) { - this.context = context; - } -} diff --git a/deprecated/starterkit/drs/controller/Stream.java b/deprecated/starterkit/drs/controller/Stream.java deleted file mode 100644 index 4fae8209..00000000 --- a/deprecated/starterkit/drs/controller/Stream.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.ga4gh.starterkit.drs.controller; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import static org.ga4gh.starterkit.drs.constant.DrsApiConstants.DRS_API_V1; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.ga4gh.starterkit.drs.utils.requesthandler.FileStreamRequestHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Stream handler, enables client to access bytes for files on the server machine - * that the client doesn't have direct access to - */ -@RestController -@RequestMapping(DRS_API_V1 + "/stream") -public class Stream { - - @Resource(name = "fileStreamRequestHandler") - private FileStreamRequestHandler fileStreamRequestHandler; - - @Autowired - private LoggingUtil loggingUtil; - - /** - * Stream file bytes for the requested DRSObject and access id - * @param objectId DRSObject identifier - * @param accessId access identifier - * @param response Spring HttpServletResponse - */ - @GetMapping(path = "/{object_id:.+}/{access_id:.+}") - public void streamFile( - @PathVariable(name = "object_id") String objectId, - @PathVariable(name = "access_id") String accessId, - HttpServletResponse response - ) { - loggingUtil.debug("Public API request: local file streaming. drs id='" + objectId + "', access id='" + accessId + "'"); - fileStreamRequestHandler.prepare(objectId, accessId, response).handleRequest(); - } -} diff --git a/deprecated/starterkit/drs/controller/package-info.java b/deprecated/starterkit/drs/controller/package-info.java deleted file mode 100644 index f8213cbb..00000000 --- a/deprecated/starterkit/drs/controller/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains REST API controller functions - */ -package org.ga4gh.starterkit.drs.controller; \ No newline at end of file diff --git a/deprecated/starterkit/drs/exception/DrsCustomExceptionHandling.java b/deprecated/starterkit/drs/exception/DrsCustomExceptionHandling.java deleted file mode 100644 index fb6b9cfd..00000000 --- a/deprecated/starterkit/drs/exception/DrsCustomExceptionHandling.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.ga4gh.starterkit.drs.exception; - -import java.time.LocalDateTime; - -import org.ga4gh.starterkit.common.constant.DateTimeConstants; -import org.ga4gh.starterkit.common.exception.CustomException; -import org.ga4gh.starterkit.common.util.webserver.CustomExceptionHandling; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; - -public class DrsCustomExceptionHandling extends CustomExceptionHandling { - - @ExceptionHandler(CustomException.class) - public ResponseEntity handleCustomExceptions(CustomException err) { - HttpStatus httpStatus = getCustomHttpStatus(err); - return yieldResponseEntity(httpStatus, err); - } - - private HttpStatus getCustomHttpStatus(CustomException err) { - return err.getClass().getAnnotation(ResponseStatus.class).value(); - } - - private ResponseEntity yieldResponseEntity(HttpStatus httpStatus, Exception ex) { - DrsCustomExceptionResponse response = new DrsCustomExceptionResponse(); - response.setTimestamp(LocalDateTime.now().format(DateTimeConstants.DATE_FORMATTER)); - response.setStatusCode(httpStatus.value()); - response.setError(httpStatus.getReasonPhrase()); - response.setMsg(ex.getMessage()); - return new ResponseEntity<>(response, httpStatus); - } -} diff --git a/deprecated/starterkit/drs/exception/DrsCustomExceptionResponse.java b/deprecated/starterkit/drs/exception/DrsCustomExceptionResponse.java deleted file mode 100644 index 70bb68e1..00000000 --- a/deprecated/starterkit/drs/exception/DrsCustomExceptionResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.ga4gh.starterkit.drs.exception; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.common.exception.CustomExceptionResponse; - -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class DrsCustomExceptionResponse extends CustomExceptionResponse { - - private String msg; - - public void setMsg(String msg) { - this.msg = msg; - } - - public String getMsg() { - return msg; - } -} diff --git a/deprecated/starterkit/drs/exception/ForbiddenException.java b/deprecated/starterkit/drs/exception/ForbiddenException.java deleted file mode 100644 index ab6185b2..00000000 --- a/deprecated/starterkit/drs/exception/ForbiddenException.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.ga4gh.starterkit.drs.exception; - -import org.ga4gh.starterkit.common.exception.CustomException; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.FORBIDDEN) -public class ForbiddenException extends CustomException { - - private static final long serialVersionUID = 1L; - - public ForbiddenException() { - super(); - } - - public ForbiddenException(String message) { - super(message); - } - - public ForbiddenException(Throwable cause) { - super(cause); - } -} diff --git a/deprecated/starterkit/drs/exception/UnauthorizedException.java b/deprecated/starterkit/drs/exception/UnauthorizedException.java deleted file mode 100644 index 6c624308..00000000 --- a/deprecated/starterkit/drs/exception/UnauthorizedException.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.ga4gh.starterkit.drs.exception; - -import org.ga4gh.starterkit.common.exception.CustomException; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.UNAUTHORIZED) -public class UnauthorizedException extends CustomException { - - private static final long serialVersionUID = 1L; - - public UnauthorizedException() { - super(); - } - - public UnauthorizedException(String message) { - super(message); - } - - public UnauthorizedException(Throwable cause) { - super(cause); - } -} diff --git a/deprecated/starterkit/drs/model/AccessMethod.java b/deprecated/starterkit/drs/model/AccessMethod.java deleted file mode 100644 index 9a1a49d3..00000000 --- a/deprecated/starterkit/drs/model/AccessMethod.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.springframework.lang.NonNull; - -/** - * Directly from DRS specification, indicates how to obtain file bytes for a - * DRSObject - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class AccessMethod { - /** - * At least one of accessId or accessUrl is required - */ - private String accessId; - - private AccessURL accessUrl; - - // Required - @NonNull - private AccessType type; - - // Optional - private String region; - - /** - * Instantiates a new AccessMethod with empty properties - */ - public AccessMethod() { - - } - - /** - * Instantiates a new AccessMethod with preconfigured accessID and access type - * @param accessID access ID - * @param type access type - */ - public AccessMethod(String accessID, AccessType type) { - this.accessId = accessID; - this.type = type; - } - - /** - * Instantiates a new AccessMethod with preconfigured accessURL and access type - * @param accessURL access URL - * @param type access type - */ - public AccessMethod(AccessURL accessURL, AccessType type) { - this.accessUrl = accessURL; - this.type = type; - } - - /** - * Instantiates a new AccessMethod with preconfigured accessID, access type, and region - * @param accessID access ID - * @param type access type - * @param region region - */ - public AccessMethod(String accessID, AccessType type, String region) { - this(accessID, type); - this.region = region; - } - - /** - * Instantiates a new AccessMethod with preconfigured access URL, access type, and region - * @param accessURL access URL - * @param type access type - * @param region region - */ - public AccessMethod(AccessURL accessURL, AccessType type, String region) { - this(accessURL, type); - this.region = region; - } - - /** - * Retrieve accessID - * @return accessID - */ - public String getAccessId() { - return accessId; - } - - /** - * Assign accessID - * @param accessId accessID - */ - public void setAccessId(String accessId) { - this.accessId = accessId; - } - - /** - * Retrieve access URL - * @return access URL - */ - public AccessURL getAccessUrl() { - return accessUrl; - } - - /** - * Assign access URL - * @param accessUrl access URL - */ - public void setAccessUrl(AccessURL accessUrl) { - this.accessUrl = accessUrl; - } - - /** - * Retrieve access type - * @return access type - */ - public AccessType getType() { - return type; - } - - /** - * Assign access type - * @param type access type - */ - public void setType(AccessType type) { - this.type = type; - } - - /** - * Retrieve region - * @return region - */ - public String getRegion() { - return region; - } - - /** - * Assign region - * @param region region - */ - public void setRegion(String region) { - this.region = region; - } -} diff --git a/deprecated/starterkit/drs/model/AccessType.java b/deprecated/starterkit/drs/model/AccessType.java deleted file mode 100644 index 90af0e3f..00000000 --- a/deprecated/starterkit/drs/model/AccessType.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - -/** - * Directly from DRS specification, enumeration of different Access Types for - * AccessMethods under a DRSObject. Access Types correspond closely with URL - * schemes for fetching file bytes (e.g. file://, https://, s3://, etc.) - */ -@JsonNaming(PropertyNamingStrategies.LowerCaseStrategy.class) -public enum AccessType { - // TODO: incorporate other data source schemes, for now only file, s3, https - s3, - // GS, - // FTP, - // GSIFTP, - // GLOBUS, - // HTSGET, - https, - file, -} diff --git a/deprecated/starterkit/drs/model/AccessURL.java b/deprecated/starterkit/drs/model/AccessURL.java deleted file mode 100644 index 6e66ec68..00000000 --- a/deprecated/starterkit/drs/model/AccessURL.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.springframework.lang.NonNull; -import java.net.URI; -import java.util.Map; - -/** - * Directly from DRS specification, contains URL and headers necessary for - * fetching file bytes of a requested DRSObject - */ -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonView(SerializeView.Public.class) -public class AccessURL { - - @NonNull - private URI url; - - private Map headers; - - /** - * Instantiates a new AccessURL object with default properties - */ - public AccessURL() { - - } - - /** - * Instantiates a new AccessURL object with preconfigured URL - * @param url URL to file bytes - */ - public AccessURL(URI url) { - this.url = url; - } - - /** - * Instantiates a new AccessURL object with preconfigured URL and headers - * @param url URL to file bytes - * @param headers headers to be provided in request to facilitate access to data (eg Auth) - */ - public AccessURL(URI url, Map headers) { - this.url = url; - this.headers = headers; - } - - /** - * Retrieve URL - * @return URL - */ - public URI getUrl() { - return url; - } - - /** - * Assign URL - * @param url URL - */ - public void setUrl(URI url) { - this.url = url; - } - - /** - * Retrieve headers - * @return headers - */ - public Map getHeaders() { - return headers; - } - - /** - * Assign headers - * @param headers headers - */ - public void setHeaders(Map headers) { - this.headers = headers; - } -} diff --git a/deprecated/starterkit/drs/model/AuthInfo.java b/deprecated/starterkit/drs/model/AuthInfo.java deleted file mode 100644 index 920bbe28..00000000 --- a/deprecated/starterkit/drs/model/AuthInfo.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - -import org.ga4gh.starterkit.drs.utils.SerializeView; - -import lombok.Getter; -import lombok.Setter; - -// Authorization information for a single DRS object -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class AuthInfo { - - @JsonView(SerializeView.Always.class) - private List supportedTypes; - - @JsonView(SerializeView.Always.class) - private List passportAuthIssuers; - - public AuthInfo() { - supportedTypes = new ArrayList<>(); - passportAuthIssuers = new ArrayList<>(); - } -} diff --git a/deprecated/starterkit/drs/model/AuthIssuer.java b/deprecated/starterkit/drs/model/AuthIssuer.java deleted file mode 100644 index 139d452d..00000000 --- a/deprecated/starterkit/drs/model/AuthIssuer.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - -import org.ga4gh.starterkit.drs.utils.SerializeView; - -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class AuthIssuer { - - @JsonView(SerializeView.Always.class) - private String brokerUrl; - - @JsonView(SerializeView.Always.class) - private String visaName; - - @JsonView(SerializeView.Always.class) - private String visaIssuer; -} diff --git a/deprecated/starterkit/drs/model/AuthType.java b/deprecated/starterkit/drs/model/AuthType.java deleted file mode 100644 index e8dcdaed..00000000 --- a/deprecated/starterkit/drs/model/AuthType.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -public enum AuthType { - None, - BasicAuth, - BearerAuth, - PassportAuth -} diff --git a/deprecated/starterkit/drs/model/AwsS3AccessObject.java b/deprecated/starterkit/drs/model/AwsS3AccessObject.java deleted file mode 100644 index 3699b312..00000000 --- a/deprecated/starterkit/drs/model/AwsS3AccessObject.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.io.Serializable; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import com.fasterxml.jackson.annotation.JsonBackReference; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.drs.utils.SerializeView; - -/** - * Inferred from DRS specification, indicates byte source for a DRSObject with - * an 's3' access type. References a file stored on AWS S3. Contains required - * info to facilitate access to an s3 file/object. - */ -@Entity -@Table(name = "aws_s3_access_object") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Admin.class) -public class AwsS3AccessObject implements Serializable, HibernateEntity { - - public static final long serialVersionUID = 1L; - - /** - * unique identifier - */ - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - @JsonIgnore - private Long id; - - /** - * AWS region where bucket is hosted - */ - @Column(name = "region") - private String region; - - /** - * AWS S3 bucket name hosting the object - */ - @Column(name = "bucket") - private String bucket; - - /** - * The key/file path to the object bytes - */ - @Column(name = "key") - private String key; - - /** - * The DRSObject associated with this access object - */ - @ManyToOne(fetch = FetchType.EAGER, - cascade = {CascadeType.PERSIST, CascadeType.MERGE, - CascadeType.DETACH, CascadeType.REFRESH}) - @JoinColumn(name = "drs_object_id") - @JsonBackReference - private DrsObject drsObject; - - /* Constructors */ - - /** - * Instantiates a new AwsS3AccessObject - */ - public AwsS3AccessObject() { - - } - - /** - * Fetch relational data that is not loaded automatically (lazy load) - */ - public void loadRelations() { - - } - - /* Setters and Getters */ - - /** - * Assign id - * @param id identifier - */ - public void setId(Long id) { - this.id = id; - } - - /** - * Retrieve id - * @return identifier - */ - public Long getId() { - return id; - } - - /** - * Assign region - * @param region AWS region - */ - public void setRegion(String region) { - this.region = region; - } - - /** - * Retrieve region - * @return AWS region - */ - public String getRegion() { - return region; - } - - /** - * Assign bucket - * @param bucket AWS bucket - */ - public void setBucket(String bucket) { - this.bucket = bucket; - } - - /** - * Retrieve bucket - * @return AWS bucket - */ - public String getBucket() { - return bucket; - } - - /** - * Assign key - * @param key key/file path to object bytes - */ - public void setKey(String key) { - this.key = key; - } - - /** - * Retrieve key - * @return key/file path to object bytes - */ - public String getKey() { - return key; - } - - /** - * Assign drsObject - * @param drsObject DrsObject associated with this access object - */ - public void setDrsObject(DrsObject drsObject) { - this.drsObject = drsObject; - } - - /** - * Retrieve drsObject - * @return DrsObject associated with this access object - */ - public DrsObject getDrsObject() { - return drsObject; - } -} diff --git a/deprecated/starterkit/drs/model/BulkAccessRequest.java b/deprecated/starterkit/drs/model/BulkAccessRequest.java deleted file mode 100644 index 84c083d7..00000000 --- a/deprecated/starterkit/drs/model/BulkAccessRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkAccessRequest { - private List selection; - - public BulkAccessRequest() { - selection = new ArrayList<>(); - } -} diff --git a/deprecated/starterkit/drs/model/BulkAuthInfoRequest.java b/deprecated/starterkit/drs/model/BulkAuthInfoRequest.java deleted file mode 100644 index f576ffac..00000000 --- a/deprecated/starterkit/drs/model/BulkAuthInfoRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.List; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkAuthInfoRequest { - private List selection; - - public BulkAuthInfoRequest() { - selection = new ArrayList<>(); - } -} diff --git a/deprecated/starterkit/drs/model/BulkAuthInfoResponse.java b/deprecated/starterkit/drs/model/BulkAuthInfoResponse.java deleted file mode 100644 index fcba244b..00000000 --- a/deprecated/starterkit/drs/model/BulkAuthInfoResponse.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.HashMap; -import java.util.Map; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkAuthInfoResponse { - - private BulkSummary summary; - private Map resolvedDrsObjectAuthInfo; - private Map unresolvedDrsObjectAuthInfo; - - public BulkAuthInfoResponse() { - summary = new BulkSummary(); - resolvedDrsObjectAuthInfo = new HashMap<>(); - unresolvedDrsObjectAuthInfo = new HashMap<>(); - } -} diff --git a/deprecated/starterkit/drs/model/BulkObjectAccessId.java b/deprecated/starterkit/drs/model/BulkObjectAccessId.java deleted file mode 100644 index ffdf077b..00000000 --- a/deprecated/starterkit/drs/model/BulkObjectAccessId.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Setter -@Getter -@NoArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkObjectAccessId { - private String objectId; - private String accessId; -} diff --git a/deprecated/starterkit/drs/model/BulkRequest.java b/deprecated/starterkit/drs/model/BulkRequest.java deleted file mode 100644 index 1fadca5b..00000000 --- a/deprecated/starterkit/drs/model/BulkRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkRequest { - private List selection; - private List passports; - - public BulkRequest() { - selection = new ArrayList<>(); - passports = new ArrayList<>(); - } -} diff --git a/deprecated/starterkit/drs/model/BulkResponse.java b/deprecated/starterkit/drs/model/BulkResponse.java deleted file mode 100644 index 35b11a00..00000000 --- a/deprecated/starterkit/drs/model/BulkResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkResponse { - - private BulkSummary summary; - private List resolvedDrsObject; - private Map unresolvedDrsObject; - - public BulkResponse() { - summary = new BulkSummary(); - resolvedDrsObject = new ArrayList<>(); - unresolvedDrsObject = new HashMap<>(); - } -} diff --git a/deprecated/starterkit/drs/model/BulkSummary.java b/deprecated/starterkit/drs/model/BulkSummary.java deleted file mode 100644 index 77066824..00000000 --- a/deprecated/starterkit/drs/model/BulkSummary.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Setter -@Getter -@NoArgsConstructor -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class BulkSummary { - private int requested; - private int resolved; - private int unresolved; -} diff --git a/deprecated/starterkit/drs/model/Checksum.java b/deprecated/starterkit/drs/model/Checksum.java deleted file mode 100644 index 3b84c073..00000000 --- a/deprecated/starterkit/drs/model/Checksum.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonBackReference; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.springframework.lang.NonNull; - -import javax.persistence.*; - -/** - * Directly from DRS specification, indicates a checksum value for a DrsObject's - * file bytes, as well as the algorithm used. - */ -@Entity -@Table(name = "drs_object_checksum") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Always.class) -public class Checksum implements HibernateEntity { - - public static final long serialVersionUID = 1L; - - /** - * Unique identifier for checksum in the database - */ - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - @JsonIgnore - private Long id; - - /** - * Checksum hash value - */ - @Column(name = "checksum") - @NonNull - private String checksum; - - /** - * Hashing algorithm used (eg md5, sha1) - */ - @Column(name = "type") - private String type; - - /** - * DrsObject that owns this checksum - */ - @ManyToOne(fetch = FetchType.EAGER, - cascade = {CascadeType.PERSIST, CascadeType.MERGE, - CascadeType.DETACH, CascadeType.REFRESH}) - @JoinColumn(name = "drs_object_id", nullable = false, insertable = true, updatable = true) - @JsonBackReference - private DrsObject drsObject; - - /** - * Instantiates a new Checksum - */ - public Checksum() { - - } - - /** - * Instantiates a new Checksum with preconfigured id, checksum, and type - * @param id unique identifier - * @param checksum checksum value - * @param type hashing algorithm - */ - public Checksum(Long id, String checksum, String type) { - this.id = id; - this.checksum = checksum; - this.type = type; - } - - /** - * Instantiates a new Checksum with preconfigured checksum, type, and drsObject - * @param checksum checksum value - * @param type hashing algorithm - * @param drsObject drsObject to which checksum belongs - */ - public Checksum(String checksum, String type, DrsObject drsObject) { - this.checksum = checksum; - this.type = type; - this.drsObject = drsObject; - } - - /** - * Fetch relational data that is not loaded automatically (lazy load) - */ - public void loadRelations() { - - } - - /** - * Assign id - * @param id identifier - */ - public void setId(Long id) { - this.id = id; - } - - /** - * Retrieve id - * @return identifier - */ - public Long getId() { - return id; - } - - /** - * Assign checksum - * @param checksum checksum value - */ - public void setChecksum(String checksum) { - this.checksum = checksum; - } - - /** - * Retrieve checksum - * @return checksum value - */ - public String getChecksum() { - return checksum; - } - - /** - * Assign type - * @param type hashing algorithm - */ - public void setType(String type) { - this.type = type; - } - - /** - * Retrieve type - * @return hashing algorithm - */ - public String getType() { - return type; - } - - /** - * Assign drsObject - * @param drsObject DrsObject owning the checksum - */ - public void setDrsObject(DrsObject drsObject) { - this.drsObject = drsObject; - } - - /** - * Retrieve drsObject - * @return DrsObject owning the checksum - */ - public DrsObject getDrsObject() { - return drsObject; - } -} diff --git a/deprecated/starterkit/drs/model/ContentsObject.java b/deprecated/starterkit/drs/model/ContentsObject.java deleted file mode 100644 index b4221e6e..00000000 --- a/deprecated/starterkit/drs/model/ContentsObject.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.springframework.lang.NonNull; -import java.net.URI; -import java.util.List; - -/** - * Directly from DRS specification, references the nested contents of a DRS - * bundle - */ -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class ContentsObject { - - /** - * Name of ContentsObject - */ - @NonNull - private String name; - - /** - * Sub-contents of this ContentsObject, indicating that there is further - * nesting. The objects within 'contents' may also contain further contents - */ - private List contents; - - /** - * Full DRS URL/URI that will enable the loading of this ContentsObject as - * a full DRSObject - */ - private List drsUri; - - /** - * DRS id - */ - private String id; - - /** - * Instantiates a new ContentsObject - */ - public ContentsObject() { - - } - - /** - * Instantiates a new ContentsObject with preset name - * @param name name of ContentsObject - */ - public ContentsObject(String name) { - this.name = name; - } - - /** - * Retrieve contents - * @return list of nested contents objects - */ - public List getContents() { - return contents; - } - - /** - * Assign contents - * @param contents list of nested contents objects - */ - public void setContents(List contents) { - this.contents = contents; - } - - /** - * Retrieve name - * @return name of contents object - */ - public String getName() { - return name; - } - - /** - * Assign name - * @param name name of contents object - */ - public void setName(String name) { - this.name = name; - } - - /** - * Retrieve DRS URI - * @return DRS URI enabling access to DRSObject outlined by this contents object - */ - public List getDrsUri() { - return drsUri; - } - - /** - * Assign DRS URI - * @param drsUri DRS URI enabling access to DRSObject outlined by this contents object - */ - public void setDrsUri(List drsUri) { - this.drsUri = drsUri; - } - - /** - * Retrieve id - * @return DRS identifier - */ - public String getId() { - return id; - } - - /** - * Assign id - * @param id DRS identifier - */ - public void setId(String id) { - this.id = id; - } -} diff --git a/deprecated/starterkit/drs/model/DrsObject.java b/deprecated/starterkit/drs/model/DrsObject.java deleted file mode 100644 index 55a28571..00000000 --- a/deprecated/starterkit/drs/model/DrsObject.java +++ /dev/null @@ -1,259 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonManagedReference; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; -import lombok.Getter; -import lombok.Setter; -import org.ga4gh.starterkit.common.constant.DateTimeConstants; -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.hibernate.Hibernate; -import org.hibernate.annotations.Cascade; -import org.hibernate.annotations.CascadeType; -import org.springframework.lang.NonNull; - -import javax.persistence.*; -import java.net.URI; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; - -/** - * Directly from DRS specification, with modifications, contains all metadata for - * a DRSObject as described in the spec. Database (entity) attributes do not - * completely align with spec attributes where more relational sophistication - * is warranted. Entity attributes can be converted to transient attributes that - * align with and fulfill the DRS spec - */ -@Entity -@Table(name = "drs_object") -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class DrsObject implements HibernateEntity { - - /* - Simple attributes lifted directly from the DRS spec: id, description, - createdTime, mimeType, name, size, updatedTime, version, aliases, - checksums - */ - - @Id - @Column(name = "id", updatable = false, nullable = false) - @NonNull - @JsonView(SerializeView.Always.class) - private String id; - - @Column(name = "description") - @JsonView(SerializeView.Always.class) - private String description; - - @Column(name = "created_time") - @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonSerialize(using = LocalDateTimeSerializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateTimeConstants.DATE_FORMAT) - @NonNull - @JsonView(SerializeView.Always.class) - private LocalDateTime createdTime; - - @Column(name = "mime_type") - @JsonView(SerializeView.Always.class) - private String mimeType; - - @Column(name = "name") - @JsonView(SerializeView.Always.class) - private String name; - - @Column(name = "size") - @JsonView(SerializeView.Always.class) - private Long size; - - @Column(name = "updated_time") - @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonSerialize(using = LocalDateTimeSerializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DateTimeConstants.DATE_FORMAT) - @JsonView(SerializeView.Always.class) - private LocalDateTime updatedTime; - - @Column(name = "version") - @JsonView(SerializeView.Always.class) - private String version; - - @ElementCollection(fetch = FetchType.LAZY) - @CollectionTable(name = "drs_object_alias", joinColumns = @JoinColumn(name = "drs_object_id")) - @Column(name = "alias") - @Cascade(value = {CascadeType.ALL}) - @JsonView({ - SerializeView.Public.class, - SerializeView.Admin.class - }) - private List aliases; - - @OneToMany(mappedBy = "drsObject", - fetch = FetchType.LAZY, - cascade = {javax.persistence.CascadeType.ALL}, - orphanRemoval = true) - @JsonView({ - SerializeView.Public.class, - SerializeView.Admin.class - }) - @JsonManagedReference - private List checksums; - - /* - Attributes capturing the parent-child relationship of DRS bundles to - nested/sub bundles, to single blob DRS Objects - */ - - @Column(name = "is_bundle") - @NonNull - @JsonView(SerializeView.Admin.class) - private Boolean isBundle; - - /** - * List of bundles to which this DRSObject belongs, ie its 'parents' - */ - @ManyToMany - @JoinTable( - name = "drs_object_bundle", - joinColumns = {@JoinColumn(name = "parent_id")}, - inverseJoinColumns = {@JoinColumn(name = "child_id")} - ) - @JsonView(SerializeView.Admin.class) - private List drsObjectChildren; - - /** - * List of sub-bundles and/or objects that this bundle has, ie its 'children' - */ - @ManyToMany - @JoinTable( - name = "drs_object_bundle", - joinColumns = {@JoinColumn(name = "child_id")}, - inverseJoinColumns = {@JoinColumn(name = "parent_id")} - ) - @JsonView(SerializeView.Admin.class) - private List drsObjectParents; - - /* - Attributes capturing multiple byte storage/access locations associated - with a single DRSObject - */ - - /** - * List of file-based byte sources, ie files local to server - */ - @OneToMany(mappedBy = "drsObject", - fetch = FetchType.LAZY, - cascade = javax.persistence.CascadeType.ALL, - orphanRemoval = true) - @JsonView(SerializeView.Admin.class) - @JsonManagedReference - private List fileAccessObjects; - - /** - * List of s3-based byte sources, ie objects on an AWS S3 bucket - */ - @OneToMany(mappedBy = "drsObject", - fetch = FetchType.LAZY, - cascade = javax.persistence.CascadeType.ALL, - orphanRemoval = true) - @JsonView(SerializeView.Admin.class) - @JsonManagedReference - private List awsS3AccessObjects; - - @ManyToMany - @JoinTable( - name = "drs_object_visa", - joinColumns = {@JoinColumn(name = "drs_object_id")}, - inverseJoinColumns = {@JoinColumn(name = "visa_id")} - ) - @JsonView(SerializeView.Admin.class) - private List passportVisas; - - /* - Transient attributes produced from transforming database records. They - are needed to conform to the DRS spec: selfURI, accessMethods, contents - */ - - /** - * self DRS URI derived from service hostname and DRS object id - */ - @Transient - @NonNull - @JsonView(SerializeView.Public.class) - private URI selfURI; - - /** - * access methods derived from all 'AccessObject' subtypes (e.g. FileAccessObjects, - * AwsS3AccessObjects) - */ - @Transient - @JsonView(SerializeView.Public.class) - private List accessMethods; - - /** - * contents objects derived from 'children' DrsObjects - */ - @Transient - @JsonView(SerializeView.Public.class) - private List contents; - - /** - * Instantiates a new DrsObject - */ - public DrsObject() { - checksums = new ArrayList<>(); - fileAccessObjects = new ArrayList<>(); - awsS3AccessObjects = new ArrayList<>(); - passportVisas = new ArrayList<>(); - } - - /* Custom API methods */ - - /** - * Fetch relational data that is not loaded automatically (lazy load) - */ - public void loadRelations() { - Hibernate.initialize(getAliases()); - Hibernate.initialize(getChecksums()); - Hibernate.initialize(getDrsObjectChildren()); - Hibernate.initialize(getDrsObjectParents()); - Hibernate.initialize(getFileAccessObjects()); - Hibernate.initialize(getAwsS3AccessObjects()); - Hibernate.initialize(getPassportVisas()); - } - - @Override - public String toString() { - return "DrsObject{" + - "id='" + id + '\'' + - ", description='" + description + '\'' + - ", createdTime=" + createdTime + - ", mimeType='" + mimeType + '\'' + - ", name='" + name + '\'' + - ", size=" + size + - ", updatedTime=" + updatedTime + - ", version='" + version + '\'' + - ", aliases=" + aliases + - ", checksums=" + checksums + - ", isBundle=" + isBundle + - ", drsObjectChildren=" + drsObjectChildren + - ", drsObjectParents=" + drsObjectParents + - ", fileAccessObjects=" + fileAccessObjects + - ", awsS3AccessObjects=" + awsS3AccessObjects + - ", passportVisas=" + passportVisas + - ", selfURI=" + selfURI + - ", accessMethods=" + accessMethods + - ", contents=" + contents + - '}'; - } -} diff --git a/deprecated/starterkit/drs/model/DrsServiceInfo.java b/deprecated/starterkit/drs/model/DrsServiceInfo.java deleted file mode 100644 index 240fee06..00000000 --- a/deprecated/starterkit/drs/model/DrsServiceInfo.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import org.ga4gh.starterkit.common.model.ServiceInfo; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.ID; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.NAME; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.DESCRIPTION; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.CONTACT_URL; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.DOCUMENTATION_URL; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.CREATED_AT; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.UPDATED_AT; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.ENVIRONMENT; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.VERSION; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.ORGANIZATION_NAME; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.ORGANIZATION_URL; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.SERVICE_TYPE_GROUP; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.SERVICE_TYPE_ARTIFACT; -import static org.ga4gh.starterkit.drs.constant.DrsServiceInfoDefaults.SERVICE_TYPE_VERSION; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - -/** - * Extension of the GA4GH base service info specification to include DRS-specific - * properties - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.LowerCamelCaseStrategy.class) -public class DrsServiceInfo extends ServiceInfo { - - /** - * Instantiates a new DrsServiceInfo object - */ - public DrsServiceInfo() { - super(); - setAllDefaults(); - } - - /** - * Sets all default properties - */ - private void setAllDefaults() { - setId(ID); - setName(NAME); - setDescription(DESCRIPTION); - setContactUrl(CONTACT_URL); - setDocumentationUrl(DOCUMENTATION_URL); - setCreatedAt(CREATED_AT); - setUpdatedAt(UPDATED_AT); - setEnvironment(ENVIRONMENT); - setVersion(VERSION); - getOrganization().setName(ORGANIZATION_NAME); - getOrganization().setUrl(ORGANIZATION_URL); - getType().setGroup(SERVICE_TYPE_GROUP); - getType().setArtifact(SERVICE_TYPE_ARTIFACT); - getType().setVersion(SERVICE_TYPE_VERSION); - } -} diff --git a/deprecated/starterkit/drs/model/Error.java b/deprecated/starterkit/drs/model/Error.java deleted file mode 100644 index d365993c..00000000 --- a/deprecated/starterkit/drs/model/Error.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - -/** - * Directly from DRS specification, error object returned to client whenever a - * server or client-side error is encountered during a DRS controller function - */ -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class Error extends Exception { - - public static final long serialVersionUID = 1L; - - private String msg; - - private int statusCode; - - /** - * Instantiates a new Error - * @param message helpful error message - * @param statusCode HTTP status code - */ - public Error(String message, int statusCode) { - this.msg = message; - this.statusCode = statusCode; - } - - /** - * Retrieve msg - * @return error message - */ - public String getMsg() { - return msg; - } - - /** - * Retrieve full message for logging purposes - * @return message indicating error code and msg - */ - public String getMessage() { - return "status_code: " + statusCode + " message: " + msg; - } - - /** - * Assign msg - * @param msg error message - */ - public void setMsg(String msg) { - this.msg = msg; - } - - /** - * Retrieve status code - * @return HTTP status code - */ - public int getStatusCode() { - return statusCode; - } - - /** - * Assign statusCode - * @param statusCode HTTP status code - */ - public void setStatusCode(int statusCode) { - this.statusCode = statusCode; - } -} diff --git a/deprecated/starterkit/drs/model/FileAccessObject.java b/deprecated/starterkit/drs/model/FileAccessObject.java deleted file mode 100644 index 36276301..00000000 --- a/deprecated/starterkit/drs/model/FileAccessObject.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonBackReference; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.drs.utils.SerializeView; - -import javax.persistence.*; -import java.io.Serializable; - -/** - * Inferred from DRS specification, indicates a byte source for a DRSObject with - * a 'file' access type. References a file that is locally available wherever - * the server is deployed. Contains required info to facilitate access to a - * local file (generally just file path) - */ -@Entity -@Table(name = "file_access_object") -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Admin.class) -public class FileAccessObject implements Serializable, HibernateEntity { - - public static final long serialVersionUID = 1L; - - @Id - @Column(name = "id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - @JsonIgnore - private Long id; - - /** - * Local file path - */ - @Column(name = "path") - private String path; - - @ManyToOne(fetch = FetchType.EAGER, - cascade = {CascadeType.PERSIST, CascadeType.MERGE, - CascadeType.DETACH, CascadeType.REFRESH}) - @JoinColumn(name = "drs_object_id") - @JsonBackReference - private DrsObject drsObject; - - /* Constructors */ - - /** - * Instantiates a new FileAccessObject - */ - public FileAccessObject() { - - } - - /** - * Instantiates a new FileAccessObject with parameters - */ - public FileAccessObject(DrsObject drsObject, String filePath) { - this.drsObject = drsObject; - this.path = filePath; - } - - /** - * Fetch relational data that is not loaded automatically (lazy load) - */ - public void loadRelations() { - - } - - /* Setters and Getters */ - - /** - * Assign id - * @param id identifier - */ - public void setId(Long id) { - this.id = id; - } - - /** - * Retrieve id - * @return identifier - */ - public Long getId() { - return id; - } - - /** - * Assign path - * @param path local file path - */ - public void setPath(String path) { - this.path = path; - } - - /** - * Retrive path - * @return local file path - */ - public String getPath() { - return path; - } - - /** - * Assign drsObject - * @param drsObject DrsObject owning this access object - */ - public void setDrsObject(DrsObject drsObject) { - this.drsObject = drsObject; - } - - /** - * Retrieve drsObject - * @return DrsObject owning this access object - */ - public DrsObject getDrsObject() { - return drsObject; - } -} diff --git a/deprecated/starterkit/drs/model/PassportBroker.java b/deprecated/starterkit/drs/model/PassportBroker.java deleted file mode 100644 index 0bba67fe..00000000 --- a/deprecated/starterkit/drs/model/PassportBroker.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; - -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.hibernate.Hibernate; -import org.springframework.lang.NonNull; -import lombok.Getter; -import lombok.Setter; - -@Entity -@Table(name = "passport_broker") -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class PassportBroker implements HibernateEntity { - - @Id - @Column(name = "url", updatable = false, nullable = false) - @NonNull - @JsonView(SerializeView.Admin.class) - private String url; - - @Column(name = "secret") - @JsonView(SerializeView.Admin.class) - private String secret; - - @OneToMany( - mappedBy = "passportBroker", - fetch = FetchType.LAZY, - cascade = {CascadeType.ALL}, - orphanRemoval = true - ) - @JsonView(SerializeView.Never.class) - private List passportVisas; - - public PassportBroker() { - passportVisas = new ArrayList<>(); - } - - public void setId(String url) { - this.url = url; - } - - public String getId() { - return url; - } - - public void loadRelations() { - Hibernate.initialize(getPassportVisas()); - } -} diff --git a/deprecated/starterkit/drs/model/PassportVisa.java b/deprecated/starterkit/drs/model/PassportVisa.java deleted file mode 100644 index 6e0e0798..00000000 --- a/deprecated/starterkit/drs/model/PassportVisa.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import lombok.Getter; -import lombok.NonNull; -import lombok.Setter; -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import org.hibernate.Hibernate; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; - -@Entity -@Table(name = "passport_visa") -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_EMPTY) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -public class PassportVisa implements HibernateEntity { - - @Id - @Column(name = "id", updatable = false, nullable = false) - @NonNull - @JsonView(SerializeView.Admin.class) - private String id; - - @Column(name = "name") - @JsonView(SerializeView.Admin.class) - private String name; - - @Column(name = "issuer") - @JsonView(SerializeView.Admin.class) - private String issuer; - - @Column(name = "secret") - @JsonView(SerializeView.Admin.class) - private String secret; - - @ManyToOne( - fetch = FetchType.EAGER, - cascade = {CascadeType.PERSIST, CascadeType.MERGE, - CascadeType.DETACH, CascadeType.REFRESH} - ) - @JoinColumn(name = "passport_broker_url") - @JsonView(SerializeView.Admin.class) - private PassportBroker passportBroker; - - @ManyToMany - @JoinTable( - name = "drs_object_visa", - joinColumns = {@JoinColumn(name = "visa_id")}, - inverseJoinColumns = {@JoinColumn(name = "drs_object_id")} - ) - @JsonView(SerializeView.Never.class) - private List drsObjects; - - public PassportVisa() { - drsObjects = new ArrayList<>(); - } - - public void loadRelations() { - Hibernate.initialize(getDrsObjects()); - } -} diff --git a/deprecated/starterkit/drs/model/PostSingleObjectRequestBody.java b/deprecated/starterkit/drs/model/PostSingleObjectRequestBody.java deleted file mode 100644 index 4e3ce090..00000000 --- a/deprecated/starterkit/drs/model/PostSingleObjectRequestBody.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.ga4gh.starterkit.drs.model; - -import java.util.ArrayList; -import java.util.List; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.databind.annotation.JsonNaming; -import org.ga4gh.starterkit.drs.utils.SerializeView; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) -@JsonView(SerializeView.Public.class) -public class PostSingleObjectRequestBody { - private boolean expand; - private List passports; - - public PostSingleObjectRequestBody() { - expand = false; - passports = new ArrayList<>(); - } -} diff --git a/deprecated/starterkit/drs/model/package-info.java b/deprecated/starterkit/drs/model/package-info.java deleted file mode 100644 index b33ec91f..00000000 --- a/deprecated/starterkit/drs/model/package-info.java +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Contains model definitions (under MVC pattern) for DRS-related views and - * controllers. Contains both database entities and non-entity models. This - * package attempts to stay closely aligned with model definitions in the DRS - * spec, but helper classes/entities have been added as needed. - * - * @since 0.1.4 - * @version 0.1.4 - */ -package org.ga4gh.starterkit.drs.model; \ No newline at end of file diff --git a/deprecated/starterkit/drs/utils/BundleRecursiveChecksumCalculator.java b/deprecated/starterkit/drs/utils/BundleRecursiveChecksumCalculator.java deleted file mode 100644 index 052c58a7..00000000 --- a/deprecated/starterkit/drs/utils/BundleRecursiveChecksumCalculator.java +++ /dev/null @@ -1,104 +0,0 @@ -package org.ga4gh.starterkit.drs.utils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.ga4gh.starterkit.drs.model.Checksum; -import org.ga4gh.starterkit.drs.model.DrsObject; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.codec.digest.MessageDigestAlgorithms; -import org.apache.commons.lang3.StringUtils; - -/* Recursively calculates checksum values for bundle-based DrsObjects based on - * the checksums of the blob-based DrsObject children it has - */ -public class BundleRecursiveChecksumCalculator { - - public static List getChecksums(DrsObject drsObject) { - return checksumMapToList(recursiveCalculateChecksums(drsObject)); - } - - public static Map recursiveCalculateChecksums(DrsObject parentDrsObject) { - Map checksumMap = null; - List childrenDrsObjects = parentDrsObject.getDrsObjectChildren(); - - if (childrenDrsObjects != null) { - if (childrenDrsObjects.size() == 0) { - checksumMap = createChecksumMapFromDrsObjectBlob(parentDrsObject); - } else { - List> childChecksumMaps = new ArrayList<>(); - for (int i = 0; i < childrenDrsObjects.size(); i++) { - childChecksumMaps.add(recursiveCalculateChecksums(childrenDrsObjects.get(i))); - } - checksumMap = mergeChecksumMaps(childChecksumMaps); - } - } - return checksumMap; - } - - private static List checksumMapToList(Map checksumMap) { - List checksumList = new ArrayList<>(); - for (String key : checksumMap.keySet()) { - Checksum checksum = new Checksum(); - checksum.setType(key); - checksum.setChecksum(checksumMap.get(key)); - checksumList.add(checksum); - } - return checksumList; - } - - private static Map createChecksumMapFromDrsObjectBlob(DrsObject drsObject) { - Map checksumMap = new HashMap<>(); - for (Checksum checksum: drsObject.getChecksums()) { - checksumMap.put(checksum.getType(), checksum.getChecksum()); - } - return checksumMap; - } - - private static Map mergeChecksumMaps(List> checksumMaps) { - // initial setup - Map mergedChecksumMap = new HashMap<>(); - Map checksumTypeCounts = new HashMap<>(); - int nMaps = checksumMaps.size(); - - // first loop, determine the checksum types shared by all children - for (Map checksumMap : checksumMaps) { - for (String key : checksumMap.keySet()) { - if (!checksumTypeCounts.containsKey(key)) { - checksumTypeCounts.put(key, 0); - } - checksumTypeCounts.put(key, checksumTypeCounts.get(key) + 1); - } - } - - // second loop, for each final checksum type, sort and concatenate values - for (String key : checksumTypeCounts.keySet()) { - if (checksumTypeCounts.get(key) == nMaps) { - List checksumValues = new ArrayList<>(); - for (Map checksumMap : checksumMaps) { - checksumValues.add(checksumMap.get(key)); - } - Collections.sort(checksumValues); - String concatenated = StringUtils.join(checksumValues, ""); - - String algorithm = null; - switch (key) { - case "md5": - algorithm = MessageDigestAlgorithms.MD5; - break; - case "sha1": - algorithm = MessageDigestAlgorithms.SHA_1; - break; - case "sha256": - algorithm = MessageDigestAlgorithms.SHA_256; - break; - } - String concatDigest = new DigestUtils(algorithm).digestAsHex(concatenated); - mergedChecksumMap.put(key, concatDigest); - } - } - return mergedChecksumMap; - } -} \ No newline at end of file diff --git a/deprecated/starterkit/drs/utils/SerializeView.java b/deprecated/starterkit/drs/utils/SerializeView.java deleted file mode 100644 index fac23e81..00000000 --- a/deprecated/starterkit/drs/utils/SerializeView.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.ga4gh.starterkit.drs.utils; - -/** - * Enables flexible serialization of different model attributes based on controller - * function. Used with the @JsonView annotation on controller functions and - * model properties to align serialized attributes with specific endpoints - */ -public class SerializeView { - - /** - * The attribute will always be serialized - */ - public static class Always {} - - /** - * The attribute will only be serialized for controllers marked 'Public', - * that is, pertaining to the public (non admin) API - */ - public static class Public extends Always {} - - /** - * The attribute will only be serialized for controllers marked 'Admin', - * that is, pertaining to private, administrative API routes - */ - public static class Admin extends Always {} - - /** - * The attribute will never be serialized - */ - public static class Never {} -} diff --git a/deprecated/starterkit/drs/utils/cache/AccessCache.java b/deprecated/starterkit/drs/utils/cache/AccessCache.java deleted file mode 100644 index 1a9211c0..00000000 --- a/deprecated/starterkit/drs/utils/cache/AccessCache.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.cache; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; - -/** - * Cache singleton storing information mapping DRS Object ids and access ids - * to the byte source for a requested DRSObject - */ -public class AccessCache { - - /** - * a cache mapping DRSObject + access id to richer AccessCacheItem info - */ - private LoadingCache cache; - - /** - * Instantiates a new AccessCache - */ - public AccessCache() { - buildCache(); - } - - /** - * Builds the cache - */ - private void buildCache() { - cache = CacheBuilder.newBuilder() - .maximumSize(1000) - .build( - new CacheLoader(){ - public AccessCacheItem load(String key) { - return new AccessCacheItem(); - } - } - ); - } - - /** - * Add a new item to the cache - * @param objectId DRS Object id - * @param accessId access id - * @param value the access cache item providing info on how to access the bytes - */ - public void put(String objectId, String accessId, AccessCacheItem value) { - cache.put(getCompositeKey(objectId, accessId), value); - } - - /** - * Retrieve an item from the cache - * @param objectId DRS Object id - * @param accessId access id - * @return the access cache item for the given ids, provides info on how to access the bytes - */ - public AccessCacheItem get(String objectId, String accessId) { - return cache.getIfPresent(getCompositeKey(objectId, accessId)); - } - - /** - * Construct a key for the cache based on DRS Object id and access id - * @param objectId DRS Object id - * @param accessId access id - * @return a composite id constructed from both ids - */ - private String getCompositeKey(String objectId, String accessId) { - return objectId.toString() + ":" + accessId; - } -} diff --git a/deprecated/starterkit/drs/utils/cache/AccessCacheItem.java b/deprecated/starterkit/drs/utils/cache/AccessCacheItem.java deleted file mode 100644 index fcc5220c..00000000 --- a/deprecated/starterkit/drs/utils/cache/AccessCacheItem.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.cache; - -import org.ga4gh.starterkit.drs.model.AccessType; - -/** - * A single item within the access cache, stores information on how to access - * the file bytes for a composite DRSObject id + access id - */ -public class AccessCacheItem { - - private String objectId; - private String accessId; - private String objectPath; - private AccessType accessType; - private String mimeType; - - /** - * Instantiates a new AccessCacheItem - */ - public AccessCacheItem() { - - } - - /** - * Assign objectId - * @param objectId DRSObject id - */ - public void setObjectId(String objectId) { - this.objectId = objectId; - } - - /** - * Retrieve objectId - * @return DRSObject id - */ - public String getObjectId() { - return objectId; - } - - /** - * Assign accessId - * @param accessId access id - */ - public void setAccessId(String accessId) { - this.accessId = accessId; - } - - /** - * Retrieve accessId - * @return access id - */ - public String getAccessId() { - return accessId; - } - - /** - * Assign objectPath - * @param objectPath path to the file bytes - */ - public void setObjectPath(String objectPath) { - this.objectPath = objectPath; - } - - /** - * Retrieve objectPath - * @return path to the file bytes - */ - public String getObjectPath() { - return objectPath; - } - - /** - * Assign accessType - * @param accessType access type for file byte source (ie URL scheme) - */ - public void setAccessType(AccessType accessType) { - this.accessType = accessType; - } - - /** - * Retrieve accessType - * @return access type for file byte source (ie URL scheme) - */ - public AccessType getAccessType() { - return accessType; - } - - /** - * Assign mimeType - * @param mimeType valid media type - */ - public void setMimeType(String mimeType) { - this.mimeType = mimeType; - } - - /** - * Retrieve mimeType - * @return valid media type - */ - public String getMimeType() { - return mimeType; - } -} diff --git a/deprecated/starterkit/drs/utils/cache/package-info.java b/deprecated/starterkit/drs/utils/cache/package-info.java deleted file mode 100644 index 0d06893c..00000000 --- a/deprecated/starterkit/drs/utils/cache/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Contains the access cache and related classes, which facilitates access to - * access URLs via a constructed access ID according to the DRS spec. - */ -package org.ga4gh.starterkit.drs.utils.cache; \ No newline at end of file diff --git a/deprecated/starterkit/drs/utils/hibernate/DrsHibernateUtil.java b/deprecated/starterkit/drs/utils/hibernate/DrsHibernateUtil.java deleted file mode 100644 index 0665b1f2..00000000 --- a/deprecated/starterkit/drs/utils/hibernate/DrsHibernateUtil.java +++ /dev/null @@ -1,330 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.hibernate; - -import org.ga4gh.starterkit.common.hibernate.HibernateEntity; -import org.ga4gh.starterkit.common.hibernate.HibernateUtil; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.ga4gh.starterkit.drs.model.Checksum; -import org.ga4gh.starterkit.drs.model.DrsObject; -import org.ga4gh.starterkit.drs.model.FileAccessObject; -import org.ga4gh.starterkit.drs.model.PassportVisa; -import org.ga4gh.starterkit.drs.utils.BundleRecursiveChecksumCalculator; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.query.Query; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.multipart.MultipartFile; - -import javax.persistence.PersistenceException; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Provides access to DRS entities/tables in the database, enabling access, creation, - * updating, and deleting of DRSObjects and associated entities - */ -public class DrsHibernateUtil extends HibernateUtil { - - /** - * Fully loads a DRS Object, performing recursive inspection/loading of child - * objects (in the case of bundles) - * - * @param id DRSObject identifier - * @param recursiveChildLoad if true, recursively load the children of each child until termini DRSObjects have been reached - * @return DRSObject with all necessary attributes loaded - * @throws HibernateException if problem encountered while interacting with db - */ - - @Autowired - private LoggingUtil loggingUtil; - - @Autowired - private HibernateUtil hibernateUtil; - - private SessionFactory sessionFactory; - - public DrsObject loadDrsObject(String id, boolean recursiveChildLoad) throws HibernateException { - Session session = newTransaction(); - DrsObject drsObject = null; - try { - drsObject = session.get(DrsObject.class, id); - if (drsObject != null) { - drsObject.loadRelations(); - - // detach entity so computed fields (size, checksum) - // aren't saved to db - session.evict(drsObject); - if (recursiveChildLoad) { - recursiveDrsObjectChildLoad(drsObject); - drsObject.setSize(recursiveSize(drsObject)); - drsObject.setChecksums(BundleRecursiveChecksumCalculator.getChecksums(drsObject)); - } - } - } catch (PersistenceException e) { - loggingUtil.error("Exception occurred: persistence exception" + e.getMessage()); - throw new HibernateException(e.getMessage()); - } catch (Exception e) { - loggingUtil.error("Exception occurred: persistence exception" + e.getMessage()); - throw new HibernateException(e.getMessage()); - } finally { - endTransaction(session); - } - return drsObject; - } - - /** - * Recursive function that loads all the children associated to a parent DrsObject. - * Recursively calls this function again if a child object has children itself. - * - * @param parentDrsObject root DRSObject to load all children for - * @return byte size sum of all recursive objects under the DrsObject node - */ - private void recursiveDrsObjectChildLoad(DrsObject parentDrsObject) { - List childrenDrsObjects = parentDrsObject.getDrsObjectChildren(); - - if (childrenDrsObjects != null) { - if (childrenDrsObjects.size() != 0) { - for (int i = 0; i < childrenDrsObjects.size(); i++) { - childrenDrsObjects.get(i).loadRelations(); - recursiveDrsObjectChildLoad(childrenDrsObjects.get(i)); - } - } - } - } - - private Long recursiveSize(DrsObject parentDrsObject) { - Long sizeSum = 0L; - List childrenDrsObjects = parentDrsObject.getDrsObjectChildren(); - - if (childrenDrsObjects != null) { - if (childrenDrsObjects.size() == 0) { - sizeSum = parentDrsObject.getSize(); - sizeSum = sizeSum == null ? 0L : sizeSum; - } else { - for (int i = 0; i < childrenDrsObjects.size(); i++) { - sizeSum += recursiveSize(childrenDrsObjects.get(i)); - } - } - } - return sizeSum; - } - - /** - * Retrieve a list of objects from the database - * - * @param The entity class to be retrieved - * @param entityClass The entity class to be retrieved - * @return List of entity objects - */ - public > List getEntityList(Class entityClass) { - Session session = newTransaction(); - List entities = null; - try { - CriteriaBuilder builder = session.getCriteriaBuilder(); - CriteriaQuery criteria = builder.createQuery(entityClass); - criteria.from(entityClass); - entities = session.createQuery(criteria).getResultList(); - } finally { - endTransaction(session); - } - return entities; - } - - public PassportVisa findPassportVisa(String visaName, String visaIssuer) { - Session session = newTransaction(); - PassportVisa visa = null; - try { - CriteriaBuilder cb = session.getCriteriaBuilder(); - CriteriaQuery cq = cb.createQuery(PassportVisa.class); - Root root = cq.from(PassportVisa.class); - Predicate[] predicates = new Predicate[2]; - predicates[0] = cb.equal(root.get("name"), visaName); - predicates[1] = cb.equal(root.get("issuer"), visaIssuer); - cq.select(root).where(predicates); - Query query = session.createQuery(cq); - List results = query.getResultList(); - if (results.size() != 1) { - String exceptionMessage = "no unique visa found"; - loggingUtil.error("Exception occurred: " + exceptionMessage); - throw new Exception(exceptionMessage); - } - visa = results.get(0); - } catch (Exception ex) { - loggingUtil.error("Exception occurred: " + ex.getMessage()); - } finally { - endTransaction(session); - } - return visa; - } - - - public void insertBulkDrsObjects(MultipartFile file) throws Exception { - List dataToInsert = new ArrayList(); - int totalSize = 0; - int processedRecords = 0; - int successfulRecords = 0; - List failedRecords = new CopyOnWriteArrayList<>(); - - try { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) { - dataToInsert = prepareDataForInsert(reader); - totalSize = dataToInsert.size(); - } catch (IOException ex) { - loggingUtil.error("Exception occurred during read: " + ex); - } - - int batchSize = 1000; - loggingUtil.info("Starting bulk insert for "+totalSize+" records."); - for (int i = 0; i < totalSize; i += batchSize) { - int toIndex = Math.min(i + batchSize, totalSize); - List batch = dataToInsert.subList(i, toIndex); - failedRecords = performBulkInsertWithExecutor(batch, 8, batchSize, failedRecords); - - int batchFailures = failedRecords.size(); // Capture failed count before next batch - successfulRecords += (batch.size() - batchFailures); - processedRecords += batch.size(); - loggingUtil.info("Processed "+processedRecords+" records out of "+totalSize); - } - loggingUtil.info("Completed bulk insert for "+totalSize+" records."); - loggingUtil.info("Inserted: "+ (totalSize - failedRecords.size())); - loggingUtil.info("Failed to insert: "+ failedRecords.size()); - } catch (Exception ex) { - loggingUtil.error("Exception during bulk insert: " + ex.getMessage()+ ex); - throw ex; - } - } - - private List prepareDataForInsert(BufferedReader reader) throws IOException { - List dataToInsert = new ArrayList<>(); - String row; - reader.readLine(); - DrsObject drsObject = null; - while ((row = reader.readLine()) != null) { - drsObject = createAndReturnDrsObject(row); - dataToInsert.add(drsObject); - } - return dataToInsert; - } - - private DrsObject createAndReturnDrsObject(String line) { - String[] fields = line.split(","); - String description = Arrays.asList(fields[1].split("/")).get(fields[1].split("/").length-1); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); - - DrsObject drsObject = new DrsObject(); - drsObject.setId(fields[0]); - drsObject.setDescription(description); - drsObject.setName(description); - drsObject.setMimeType(fields[2]); - drsObject.setSize(Long.valueOf(fields[3])); - drsObject.setUpdatedTime(LocalDateTime.parse(fields[4], formatter)); - drsObject.setCreatedTime(LocalDateTime.parse(fields[5], formatter)); - if(fields[1] != null) { - List files = createAndReturnFileObjects(drsObject, fields[1]); - drsObject.setFileAccessObjects(files); - } - if(fields[6] != null || fields[7] != null || fields[8] != null) { - List checksums = createAndReturnChecksums(drsObject, fields[6], fields[7], fields[8]); - drsObject.setChecksums(checksums); - } - - return drsObject; - } - - private List createAndReturnChecksums(DrsObject drsObject, String cMD5, String cSHA1, String cSHA256) { - Checksum md5 = new Checksum(cMD5,"md5", drsObject); - Checksum sha1 = new Checksum(cSHA1,"sha1", drsObject); - Checksum sha256 = new Checksum(cSHA256,"sha256", drsObject); - /* - if(drsObject.getId().equals("")) { - sha256 = new Checksum(cSHA256,"sha512", drsObject); - } - */ - - return List.of(md5, sha1, sha256); - } - - private List createAndReturnFileObjects(DrsObject drsObject, String field) { - String[] filePaths = field.split(","); - return Stream.of(filePaths) - .map(path -> new FileAccessObject(drsObject, path)) - .collect(Collectors.toList()); - } - - public > List performBulkInsertWithExecutor( - List objectList, int numThreads, int batchSize, List failedRecords) throws Exception { - - ExecutorService executor = Executors.newFixedThreadPool(numThreads); - List>> futures = new ArrayList<>(); - int totalSize = objectList.size(); - - try { - for (int i = 0; i < totalSize; i += batchSize) { - List batch = objectList.subList(i, Math.min(i + batchSize, totalSize)); - - futures.add(executor.submit(() -> { - List failedBatch = new ArrayList<>(); - - Session session = null; - Transaction tx = null; - - try { - Method method = HibernateUtil.class.getDeclaredMethod("getSessionFactory"); - method.setAccessible(true); // Bypass private access - SessionFactory sessionFactory = (SessionFactory) method.invoke(hibernateUtil); - - session = sessionFactory.openSession(); - tx = session.beginTransaction(); - for (DrsObject object : batch) { - try { - session.save(object); - } catch (HibernateException ex) { - loggingUtil.error("HibernateException occurred: " + ex); - failedBatch.add(object); - } - } - session.flush(); - session.clear(); - tx.commit(); - } catch (Exception ex) { - if (tx != null) { - tx.rollback(); - } - loggingUtil.error("Transaction rolled back due to: " + ex); - throw ex; - - } finally { - if (session != null && session.isOpen()) { - session.close(); - } - } - return failedBatch; - })); - } - - List allFailedRecords = new ArrayList<>(); - for (Future> future : futures) { - allFailedRecords.addAll(future.get()); - } - return allFailedRecords; - } finally { - executor.shutdown(); - } - } -} diff --git a/deprecated/starterkit/drs/utils/hibernate/package-info.java b/deprecated/starterkit/drs/utils/hibernate/package-info.java deleted file mode 100644 index 83d0e9fa..00000000 --- a/deprecated/starterkit/drs/utils/hibernate/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Custom hibernate-related classes for facilitating access to DRS entities in - * the database via hibernate API - */ -package org.ga4gh.starterkit.drs.utils.hibernate; \ No newline at end of file diff --git a/deprecated/starterkit/drs/utils/package-info.java b/deprecated/starterkit/drs/utils/package-info.java deleted file mode 100644 index e9848811..00000000 --- a/deprecated/starterkit/drs/utils/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Helper/utility classes for various uses throughout the DRS service application - */ -package org.ga4gh.starterkit.drs.utils; \ No newline at end of file diff --git a/deprecated/starterkit/drs/utils/passport/UserPassport.java b/deprecated/starterkit/drs/utils/passport/UserPassport.java deleted file mode 100644 index 167025a4..00000000 --- a/deprecated/starterkit/drs/utils/passport/UserPassport.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.passport; - -import java.util.HashMap; -import java.util.Map; - -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -public class UserPassport { - - private String passportJwt; - private Map visaJwtMap; - - public UserPassport() { - visaJwtMap = new HashMap<>(); - } -} diff --git a/deprecated/starterkit/drs/utils/passport/UserPassportMap.java b/deprecated/starterkit/drs/utils/passport/UserPassportMap.java deleted file mode 100644 index e6b6d28a..00000000 --- a/deprecated/starterkit/drs/utils/passport/UserPassportMap.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.passport; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import com.auth0.jwt.JWT; -import com.auth0.jwt.interfaces.DecodedJWT; -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -public class UserPassportMap { - - private Map map; - - public UserPassportMap(List passports) { - map = new HashMap<>(); - - for (String rawPassportJwt : passports) { - UserPassport userPassport = new UserPassport(); - userPassport.setPassportJwt(rawPassportJwt); - - DecodedJWT decodedPassportJwt = JWT.decode(rawPassportJwt); - String passportIss = decodedPassportJwt.getClaim("iss").asString(); - - String[] containedVisas = decodedPassportJwt.getClaim("contained_visas").asArray(String.class); - String[] rawVisaJwts = decodedPassportJwt.getClaim("ga4gh_passport_v1").asArray(String.class); - for (int i = 0; i < containedVisas.length; i++) { - String containedVisa = containedVisas[i]; - String rawVisaJwt = rawVisaJwts[i]; - userPassport.getVisaJwtMap().put(containedVisa, rawVisaJwt); - } - map.put(passportIss, userPassport); - } - } - - public void verifyAllJwts() { - - } -} diff --git a/deprecated/starterkit/drs/utils/passport/UserPassportMapVerifier.java b/deprecated/starterkit/drs/utils/passport/UserPassportMapVerifier.java deleted file mode 100644 index b7263046..00000000 --- a/deprecated/starterkit/drs/utils/passport/UserPassportMapVerifier.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.passport; - -import com.auth0.jwt.JWT; -import com.auth0.jwt.JWTVerifier; -import com.auth0.jwt.algorithms.Algorithm; - -import org.ga4gh.starterkit.common.exception.BadRequestException; -import org.ga4gh.starterkit.drs.exception.UnauthorizedException; -import org.ga4gh.starterkit.drs.model.PassportBroker; -import org.ga4gh.starterkit.drs.model.PassportVisa; -import org.ga4gh.starterkit.drs.utils.hibernate.DrsHibernateUtil; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.springframework.beans.factory.annotation.Autowired; - -import lombok.Getter; -import lombok.Setter; - -@Setter -@Getter -public class UserPassportMapVerifier { - - @Autowired - private DrsHibernateUtil hibernateUtil; - - @Autowired - private LoggingUtil loggingUtil; - - public void verifyAll(UserPassportMap userPassportMap) { - try { - for (String passportIssKey : userPassportMap.getMap().keySet()) { - // verify the passport-level JWT - // first find the secret from the DB - // then use it to verify - UserPassport userPassport = userPassportMap.getMap().get(passportIssKey); - String rawPassportJwt = userPassport.getPassportJwt(); - PassportBroker passportBroker = hibernateUtil.readEntityObject(PassportBroker.class, passportIssKey, false); - if (passportBroker == null) { - String exceptionMessage = "Passports from issuer: '" + passportIssKey + "' are not accepted here."; - loggingUtil.error("Exception occurred: passport broker is null " + exceptionMessage); - throw new Exception(exceptionMessage); - } - String passportBrokerSecret = passportBroker.getSecret(); - JWTVerifier passportVerifier = JWT.require(Algorithm.HMAC256(passportBrokerSecret)).build(); - passportVerifier.verify(rawPassportJwt); - - for (String visaKey : userPassport.getVisaJwtMap().keySet()) { - String rawVisaJwt = userPassport.getVisaJwtMap().get(visaKey); - String visaName = visaKey.split("@")[0]; - String visaIssuer = visaKey.split("@")[1]; - PassportVisa registeredVisa = hibernateUtil.findPassportVisa(visaName, visaIssuer); - if (registeredVisa == null) { - String exceptionMessage = "The Visa you provided: '" + visaKey + "' is not accepted here."; - loggingUtil.error("Exception occurred: registered visa is null " + exceptionMessage); - throw new Exception(exceptionMessage); - } - String visaSecret = registeredVisa.getSecret(); - JWTVerifier visaVerifier = JWT.require(Algorithm.HMAC256(visaSecret)).build(); - visaVerifier.verify(rawVisaJwt); - } - } - } catch (Exception ex) { - String message = "Invalid Passport(s), message: " + ex.getMessage(); - loggingUtil.error("Exception occurred: " + message); - throw new UnauthorizedException(message); - } - } -} diff --git a/deprecated/starterkit/drs/utils/requesthandler/AccessRequestHandler.java b/deprecated/starterkit/drs/utils/requesthandler/AccessRequestHandler.java deleted file mode 100644 index a2ad63fe..00000000 --- a/deprecated/starterkit/drs/utils/requesthandler/AccessRequestHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.requesthandler; - -import java.net.URI; -import org.ga4gh.starterkit.common.config.ServerProps; -import static org.ga4gh.starterkit.drs.constant.DrsApiConstants.DRS_API_V1; -import org.ga4gh.starterkit.common.exception.ResourceNotFoundException; -import org.ga4gh.starterkit.common.requesthandler.RequestHandler; -import org.ga4gh.starterkit.common.util.logging.LoggingUtil; -import org.ga4gh.starterkit.drs.model.AccessURL; -import org.ga4gh.starterkit.drs.utils.cache.AccessCache; -import org.ga4gh.starterkit.drs.utils.cache.AccessCacheItem; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Request handling logic for providing an AccessURL from a provided DrsObject id - * and access ID - */ -public class AccessRequestHandler implements RequestHandler { - - @Autowired - private ServerProps serverProps; - - @Autowired - private AccessCache accessCache; - - @Autowired - private LoggingUtil loggingUtil; - - private String objectId; - private String accessId; - - /** - * Instantiates a new AccessRequestHandler - */ - public AccessRequestHandler() { - - } - - /** - * Prepares the request handler with input params from the controller function - * @param objectId DrsObject identifier - * @param accessId access identifier - * @return the prepared request handler - */ - public AccessRequestHandler prepare(String objectId, String accessId) { - this.objectId = objectId; - this.accessId = accessId; - return this; - } - - /** - * Provides an AccessURL for the given DrsObject id and access ID - */ - public AccessURL handleRequest() { - AccessCacheItem cacheItem = accessCache.get(objectId, accessId); - if (cacheItem == null) { - String exceptionMessage = "invalid access_id/object_id " + accessId + '/' + objectId; - loggingUtil.error("Exception occurred: " + exceptionMessage); - throw new ResourceNotFoundException(exceptionMessage); - } - - AccessURL accessURL = generateAccessURLForFile(); - return accessURL; - } - - /** - * Constructs the streaming endpoint URL for the given ids - * @return AccessURL pointing to this service's streaming endpoint - */ - private AccessURL generateAccessURLForFile() { - String path = DRS_API_V1 + "/stream/" + objectId + "/" + accessId; - - StringBuffer uriBuffer = new StringBuffer(serverProps.getScheme() + "://"); - uriBuffer.append(serverProps.getHostname()); - if (!serverProps.getPublicApiPort().equals("80")) { - uriBuffer.append(":" + serverProps.getPublicApiPort()); - } - uriBuffer.append(path); - return new AccessURL(URI.create(uriBuffer.toString())); - } -} diff --git a/deprecated/starterkit/drs/utils/requesthandler/AuthInfoRequestHandler.java b/deprecated/starterkit/drs/utils/requesthandler/AuthInfoRequestHandler.java deleted file mode 100644 index 867ffe85..00000000 --- a/deprecated/starterkit/drs/utils/requesthandler/AuthInfoRequestHandler.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.requesthandler; - -import org.ga4gh.starterkit.common.exception.ResourceNotFoundException; -import org.ga4gh.starterkit.common.requesthandler.RequestHandler; -import org.ga4gh.starterkit.drs.model.AuthInfo; -import org.ga4gh.starterkit.drs.model.AuthIssuer; -import org.ga4gh.starterkit.drs.model.AuthType; -import org.ga4gh.starterkit.drs.model.DrsObject; -import org.ga4gh.starterkit.drs.model.PassportVisa; -import org.ga4gh.starterkit.drs.utils.hibernate.DrsHibernateUtil; -import org.springframework.beans.factory.annotation.Autowired; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Setter -@Getter -@NoArgsConstructor -public class AuthInfoRequestHandler implements RequestHandler { - - @Autowired - private DrsHibernateUtil hibernateUtil; - - private String objectId; - - public AuthInfoRequestHandler prepare(String objectId) { - this.objectId = objectId; - return this; - } - - public AuthInfo handleRequest() { - AuthInfo authInfo = new AuthInfo(); - - DrsObject drsObject = hibernateUtil.loadDrsObject(objectId, false); - if (drsObject == null) { - throw new ResourceNotFoundException("No DrsObject found by id: " + objectId); - } - - if (drsObject.getPassportVisas().size() == 0) { - authInfo.getSupportedTypes().add(AuthType.None); - } else { - authInfo.getSupportedTypes().add(AuthType.PassportAuth); - - for (PassportVisa visa : drsObject.getPassportVisas()) { - AuthIssuer issuer = new AuthIssuer(); - issuer.setBrokerUrl(visa.getPassportBroker().getId()); - issuer.setVisaName(visa.getName()); - issuer.setVisaIssuer(visa.getIssuer()); - authInfo.getPassportAuthIssuers().add(issuer); - } - } - System.out.println("what is auth info??"); - System.out.println(authInfo.getSupportedTypes().size()); - System.out.println(authInfo.getSupportedTypes().get(0)); - return authInfo; - } -} diff --git a/deprecated/starterkit/drs/utils/requesthandler/FileStreamRequestHandler.java b/deprecated/starterkit/drs/utils/requesthandler/FileStreamRequestHandler.java deleted file mode 100644 index aebfb329..00000000 --- a/deprecated/starterkit/drs/utils/requesthandler/FileStreamRequestHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.requesthandler; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.io.IOUtils; -import org.ga4gh.starterkit.common.exception.ResourceNotFoundException; -import org.ga4gh.starterkit.common.requesthandler.RequestHandler; -import org.ga4gh.starterkit.drs.utils.cache.AccessCache; -import org.ga4gh.starterkit.drs.utils.cache.AccessCacheItem; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Enables handling logic for the streaming endpoint, allows files stored on the - * service's file system to be streamed over the API - */ -public class FileStreamRequestHandler implements RequestHandler { - - @Autowired - private AccessCache accessCache; - - private String objectId; - private String accessId; - private HttpServletResponse response; - - /** - * Prepares the request handler with input params from the controller function - * @param objectId DrsObject identifier - * @param accessId access identifier - * @param response low-level Spring response object handling file streaming - * @return the prepared request handler - */ - public FileStreamRequestHandler prepare(String objectId, String accessId, HttpServletResponse response) { - this.objectId = objectId; - this.accessId = accessId; - this.response = response; - return this; - } - - /** - * Streams the file contents referenced by the provided object id and access id - * to client - */ - public Void handleRequest() { - // look up the access cache to see if a valid set of object id and - // access id was provided - AccessCacheItem cacheItem = accessCache.get(objectId, accessId); - if (cacheItem == null) { - throw new ResourceNotFoundException("invalid access_id/object_id"); - } - - try { - // Open file input stream - InputStream inputStream = new FileInputStream(new File(cacheItem.getObjectPath())); - - // Set Response headers - response.addHeader("Content-Disposition", "attachment"); - if (cacheItem.getMimeType() != null) { - response.setContentType(cacheItem.getMimeType()); - } - - // copy file input stream to response's output stream - IOUtils.copy(inputStream, response.getOutputStream()); - response.flushBuffer(); - } catch (IOException e) { - // TODO THROW REST CONTROLLER EXCEPTION - return null; - } - - return null; - } -} diff --git a/deprecated/starterkit/drs/utils/requesthandler/ObjectRequestHandler.java b/deprecated/starterkit/drs/utils/requesthandler/ObjectRequestHandler.java deleted file mode 100644 index b411d557..00000000 --- a/deprecated/starterkit/drs/utils/requesthandler/ObjectRequestHandler.java +++ /dev/null @@ -1,284 +0,0 @@ -package org.ga4gh.starterkit.drs.utils.requesthandler; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import org.ga4gh.starterkit.common.config.ServerProps; -import org.ga4gh.starterkit.common.exception.ResourceNotFoundException; -import org.ga4gh.starterkit.common.requesthandler.RequestHandler; -import org.ga4gh.starterkit.drs.config.DrsServiceProps; -import org.ga4gh.starterkit.drs.exception.ForbiddenException; -import org.ga4gh.starterkit.drs.exception.UnauthorizedException; -import org.ga4gh.starterkit.drs.model.AccessMethod; -import org.ga4gh.starterkit.drs.model.AccessType; -import org.ga4gh.starterkit.drs.model.AccessURL; -import org.ga4gh.starterkit.drs.model.AwsS3AccessObject; -import org.ga4gh.starterkit.drs.model.ContentsObject; -import org.ga4gh.starterkit.drs.model.DrsObject; -import org.ga4gh.starterkit.drs.model.FileAccessObject; -import org.ga4gh.starterkit.drs.model.PassportVisa; -import org.ga4gh.starterkit.drs.utils.cache.AccessCache; -import org.ga4gh.starterkit.drs.utils.cache.AccessCacheItem; -import org.ga4gh.starterkit.drs.utils.hibernate.DrsHibernateUtil; -import org.ga4gh.starterkit.drs.utils.passport.UserPassport; -import org.ga4gh.starterkit.drs.utils.passport.UserPassportMap; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * Request handling logic for loading a DRSObject and formatting it according - * to the DRS specification - */ -public class ObjectRequestHandler implements RequestHandler { - - @Autowired - ServerProps serverProps; - - @Autowired - DrsServiceProps drsServiceProps; - - @Autowired - AccessCache accessCache; - - @Autowired - DrsHibernateUtil hibernateUtil; - - private String objectId; - - private boolean expand; - - private UserPassportMap userPassportMap; - - /* Constructors */ - - /** - * Instantiate a new ObjectRequestHandler - */ - public ObjectRequestHandler() { - - } - - /** - * Prepares the request handler with input params from the controller function - * @param objectId DrsObject identifier - * @param expand boolean indicating whether to return nested/recursive bundles under 'contents' - * @return the prepared request handler - */ - public ObjectRequestHandler prepare(String objectId, boolean expand, UserPassportMap userPassportMap) { - this.objectId = objectId; - this.expand = expand; - this.userPassportMap = userPassportMap; - return this; - } - - /** - * Obtains information about a DRSObject and formats it to the DRS specification - */ - public DrsObject handleRequest() { - // Get DrsObject from db - DrsObject drsObject = hibernateUtil.loadDrsObject(objectId, true); - if (drsObject == null) { - throw new ResourceNotFoundException("No DrsObject found by id: " + objectId); - } - - // check if DrsObject requires auth, if so verify the client's passport - List requiredVisas = drsObject.getPassportVisas(); - boolean requiresAuth = false; - if (requiredVisas != null && requiredVisas.size() > 0) { - requiresAuth = true; - } - boolean noPassport = userPassportMap == null || userPassportMap.getMap().size() == 0; - if (requiresAuth) { - if (noPassport) { - throw new UnauthorizedException("Request for controlled data is missing user passport(s)"); - } - - // need to verify at least 1 visa registered with the DRS Object - boolean matchingVisaFound = false; - for (PassportVisa drsObjectRegisteredVisa : drsObject.getPassportVisas()) { - String passportBrokerIss = drsObjectRegisteredVisa.getPassportBroker().getUrl(); - String visaName = drsObjectRegisteredVisa.getName(); - String visaIssuer = drsObjectRegisteredVisa.getIssuer(); - UserPassport userPassport = userPassportMap.getMap().get(passportBrokerIss); - if (userPassport != null) { - String visaKey = visaName + "@" + visaIssuer; - String visaJwt = userPassport.getVisaJwtMap().get(visaKey); - if (visaJwt != null) { - matchingVisaFound = true; - } - } - } - - if (! matchingVisaFound) { - throw new ForbiddenException("No suitable visa found in user passport(s) for requested DRS object"); - } - } - - // post query prep of response - drsObject.setSelfURI(prepareSelfURI(objectId)); - drsObject.setContents(prepareContents(drsObject)); - drsObject.setAccessMethods(prepareAccessMethods(drsObject)); - return drsObject; - } - - /** - * Constructs the self URI from server hostname and object id - * @param id DrsObject identifier - * @return self-referencing URI - */ - private URI prepareSelfURI(String id) { - StringBuffer uriBuffer = new StringBuffer("drs://"); - uriBuffer.append(serverProps.getHostname()); - if (!serverProps.getPublicApiPort().equals("80")) { - uriBuffer.append(":" + serverProps.getPublicApiPort()); - } - uriBuffer.append("/" + id.toString()); - return URI.create(uriBuffer.toString()); - } - - /** - * Constructs the contents object list from a DrsObject's children - * @param drsObject DrsObject with loaded children - * @return List of contents objects derived from children - */ - private List prepareContents(DrsObject drsObject) { - List contents = new ArrayList<>(); - for (int i = 0; i < drsObject.getDrsObjectChildren().size(); i++) { - contents.add(createContentsObject(drsObject.getDrsObjectChildren().get(i))); - } - return contents; - } - - /** - * Constructs a single contents object from a DrsObject - * @param drsObject DrsObject to be converted into a ContentsObject - * @return ContentsObject derived from the DrsObject - */ - private ContentsObject createContentsObject(DrsObject drsObject) { - ContentsObject contentsObject = new ContentsObject(); - contentsObject.setId(drsObject.getId()); - contentsObject.setDrsUri(new ArrayList(){{ - add(prepareSelfURI(drsObject.getId())); - }}); - contentsObject.setName(drsObject.getName()); - - // if 'expand' boolean is true, perform recursive function to recursively - // convert all children DrsObjects to ContentsObjects - if (expand) { - List childContents = new ArrayList<>(); - for (int i = 0; i < drsObject.getDrsObjectChildren().size(); i++) { - childContents.add(createContentsObject(drsObject.getDrsObjectChildren().get(i))); - } - contentsObject.setContents(childContents); - } - - return contentsObject; - } - - /** - * Constructs a combined list of access methods from all different types - * of AccessObjects (eg FileAccessObjects, AwsS3AccessObjects) - * @param drsObject the DrsObject for which the access methods list will be constructed - * @return list of access methods - */ - private List prepareAccessMethods(DrsObject drsObject) { - - List accessMethods = new ArrayList<>(); - - // Convert file-based access objects to AccessMethods - // if indicated by the DrsServiceProps, return a 'file://' URL indicating - // the direct path and/or an 'http(s)://' URL pointing to the streaming - // endpoint - for (FileAccessObject fileAccessObject : drsObject.getFileAccessObjects()) { - if (drsServiceProps.getServeFileURLForFileObjects()) { - accessMethods.add(createFileURLAccessMethodForFileObject(fileAccessObject)); - } - if (drsServiceProps.getServeStreamURLForFileObjects()) { - accessMethods.add(createStreamAccessMethodForFileObject(fileAccessObject)); - } - } - - // Convert s3-based access objects to AccessMethods - for (AwsS3AccessObject awsS3AccessObject : drsObject.getAwsS3AccessObjects()) { - accessMethods.add(createAccessMethod(awsS3AccessObject)); - } - - return accessMethods; - } - - /** - * Construct a file:// URL for a file-based access object - * @param fileAccessObject file-based access object - * @return access method with a file:// URL - */ - private AccessMethod createFileURLAccessMethodForFileObject(FileAccessObject fileAccessObject) { - AccessMethod accessMethod = new AccessMethod(); - accessMethod.setType(AccessType.file); - AccessURL accessURL = new AccessURL(URI.create( - "file://" + fileAccessObject.getPath() - )); - accessMethod.setAccessUrl(accessURL); - return accessMethod; - } - - /** - * Construct an http(s):// URL pointing to streaming endpoint for a file-based access object - * @param fileAccessObject file-based access object - * @return access method with a http(s):// URL - */ - private AccessMethod createStreamAccessMethodForFileObject(FileAccessObject fileAccessObject) { - AccessMethod accessMethod = new AccessMethod(); - accessMethod.setType(AccessType.https); - - // populate the cache with a new item containing the access ID so it - // can be recgonized by the access endpoint - String accessID = UUID.randomUUID().toString(); - AccessCacheItem accessCacheItem = generateAccessCacheItem( - fileAccessObject.getDrsObject().getId(), - accessMethod.getAccessId(), - fileAccessObject.getPath(), - accessMethod.getType(), - fileAccessObject.getDrsObject().getMimeType()); - accessCache.put(fileAccessObject.getDrsObject().getId(), accessID, accessCacheItem); - - accessMethod.setAccessId(accessID); - return accessMethod; - } - - /** - * Construct an s3:// URL for an s3-based access object - * @param awsS3AccessObject S3-based access object - * @return access method with s3:// URL - */ - private AccessMethod createAccessMethod(AwsS3AccessObject awsS3AccessObject) { - AccessMethod accessMethod = new AccessMethod(); - accessMethod.setType(AccessType.s3); - accessMethod.setRegion(awsS3AccessObject.getRegion()); - - AccessURL accessURL = new AccessURL(URI.create( - "s3://" + awsS3AccessObject.getBucket() - + awsS3AccessObject.getKey())); - accessMethod.setAccessUrl(accessURL); - return accessMethod; - - } - - /** - * Create an access cache item with the supplied parameters - * @param objectId DrsObject identifier - * @param accessId access id - * @param objectPath file path/URL to byte source - * @param accessType path/URL type - * @param mimeType media type - * @return access cache item populated with the supplied parameters - */ - private AccessCacheItem generateAccessCacheItem(String objectId, String accessId, String objectPath, AccessType accessType, String mimeType) { - AccessCacheItem item = new AccessCacheItem(); - item.setObjectId(objectId); - item.setAccessId(accessId); - item.setObjectPath(objectPath); - item.setAccessType(accessType); - item.setMimeType(mimeType); - return item; - } -} diff --git a/deprecated/starterkit/drs/utils/requesthandler/package-info.java b/deprecated/starterkit/drs/utils/requesthandler/package-info.java deleted file mode 100644 index 60900de9..00000000 --- a/deprecated/starterkit/drs/utils/requesthandler/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Contains classes that harbor the main logic for controller functions, - * abstracting it away from the 'controller' package. Request handlers are - * ephemeral and loaded on a per-request basis - */ -package org.ga4gh.starterkit.drs.utils.requesthandler; \ No newline at end of file diff --git a/liquibase/dbchangelog.xml b/liquibase/dbchangelog.xml index 5ca1d12a..65460e43 100644 --- a/liquibase/dbchangelog.xml +++ b/liquibase/dbchangelog.xml @@ -169,4 +169,14 @@ + + + + + + + + + + diff --git a/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetPublicController.java b/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetPublicController.java index a4155628..cd92d336 100644 --- a/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetPublicController.java +++ b/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetPublicController.java @@ -1,11 +1,14 @@ package org.ga4gh.refcloud.api.core.dataset; +import org.springframework.data.domain.Page; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; + +import org.ga4gh.refcloud.api.drs.drsobject.DrsObject; import org.ga4gh.refcloud.api.security.KratosSessionResponse.Identity; -import org.springframework.web.bind.annotation.PostMapping; @RestController @RequestMapping("/datasets") @@ -34,4 +37,17 @@ public ResponseEntity requestAccessToDatasetById(@Authentica DatasetResponseDTO dataset = datasetService.requestAccessToDatasetById(identity.getId(), datasetId); return ResponseEntity.ok(dataset); } + + @GetMapping("/{datasetId}/manifests") + @PreAuthorize("@GA4GHPassportTokenEvaluator.canAccessDataset(authentication, #datasetId)") + public ResponseEntity> getManifestsForDataset( + @PathVariable String datasetId, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size, + @RequestParam(defaultValue = "id") String sortBy, + @RequestParam(defaultValue = "asc") String direction + ) { + Page manifestDtoPage = datasetService.getDrsObjectManifestsForDataset(datasetId, page, size, sortBy, direction); + return ResponseEntity.ok(manifestDtoPage); + } } diff --git a/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetService.java b/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetService.java index 98037993..ab61ea76 100644 --- a/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetService.java +++ b/src/main/java/org/ga4gh/refcloud/api/core/dataset/DatasetService.java @@ -1,13 +1,22 @@ package org.ga4gh.refcloud.api.core.dataset; import org.ga4gh.refcloud.api.core.tag.Tag; +import org.ga4gh.refcloud.api.drs.drsobject.DrsObject; +import org.ga4gh.refcloud.api.drs.drsobject.DrsObjectRepository; +import org.ga4gh.refcloud.api.drs.drsobject.DrsObjectService; +import org.ga4gh.refcloud.api.exception.ResourceNotFoundException; import org.ga4gh.refcloud.api.passport.passportuser.PassportUser; import org.ga4gh.refcloud.api.passport.passportuser.PassportUserRepository; import org.ga4gh.refcloud.api.passport.passportuservisaassertion.PassportUserVisaAssertion; import org.ga4gh.refcloud.api.passport.passportuservisaassertion.PassportUserVisaAssertionRepository; import org.ga4gh.refcloud.api.passport.passportuservisaassertion.PassportUserVisaAssertionResponseDTO; +import org.ga4gh.refcloud.api.passport.passportuservisaassertion.PassportUserVisaAssertionService; import org.ga4gh.refcloud.api.passport.passportuservisaassertion.PassportVisaAssertionStatus; import org.ga4gh.refcloud.api.passport.passportvisa.PassportVisaResponseDTO; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; @@ -23,14 +32,20 @@ public class DatasetService { private final DatasetRepository datasetRepository; + private final PassportUserVisaAssertionService passportUserVisaAssertionService; + private final PassportUserRepository passportUserRepository; private final PassportUserVisaAssertionRepository passportUserVisaAssertionRepository; - public DatasetService(DatasetRepository datasetRepository, PassportUserRepository passportUserRepository, PassportUserVisaAssertionRepository passportUserVisaAssertionRepository) { + private final DrsObjectRepository drsObjectRepository; + + public DatasetService(DatasetRepository datasetRepository, PassportUserVisaAssertionService passportUserVisaAssertionService, PassportUserRepository passportUserRepository, PassportUserVisaAssertionRepository passportUserVisaAssertionRepository, DrsObjectRepository drsObjectRepository) { this.datasetRepository = datasetRepository; + this.passportUserVisaAssertionService = passportUserVisaAssertionService; this.passportUserRepository = passportUserRepository; this.passportUserVisaAssertionRepository = passportUserVisaAssertionRepository; + this.drsObjectRepository = drsObjectRepository; } @Transactional(readOnly = true) @@ -79,6 +94,12 @@ public DatasetResponseDTO getDatasetById(String userId, String datasetId) { return convertToResponseDto(dataset, assertion); } + @Transactional(readOnly = true) + public String getVisaIdByDatasetId(String id) { + Dataset dataset = loadDataset(id); + return dataset.getPassportVisa().getId(); + } + @Transactional public DatasetResponseDTO requestAccessToDatasetById(String userId, String datasetId) { // retrieve dataset & visa object from db @@ -109,6 +130,45 @@ public DatasetResponseDTO requestAccessToDatasetById(String userId, String datas return convertToResponseDto(dataset, assertion); } + @Transactional + public Page getDrsObjectManifestsForDataset(String datasetId, int page, int size, String sortBy, String direction) { + Sort sort = direction.equalsIgnoreCase("desc") ? + Sort.by(sortBy).descending() : + Sort.by(sortBy).ascending(); + Pageable pageable = PageRequest.of(page, size, sort); + Page drsObjectsPage = drsObjectRepository.findDrsObjectManifestsByDatasetId(datasetId, pageable); + Page manifestDtoPage = drsObjectsPage.map(drsObject -> new ManifestResponseDTO( + drsObject.getId(), + drsObject.getName(), + drsObject.getSize(), + drsObject.getCreatedTime(), + drsObject.getUpdatedTime(), + drsObject.getVersion(), + drsObject.getMimeType(), + drsObject.getDescription(), + drsObject.getIsManifest(), + drsObject.getManifestContent() + )); + return manifestDtoPage; + } + + public boolean validateUserIsAuthorizedForDataset(String userId, String datasetId) { + String visaId = getVisaIdByDatasetId(datasetId); + Optional optionalAssertion = passportUserVisaAssertionService.getAssertionByUserIdAndVisaId(userId, visaId); + if (optionalAssertion.isPresent()) { + PassportUserVisaAssertion assertion = optionalAssertion.get(); + if (assertion.getCurrentStatus() == PassportVisaAssertionStatus.Approved) { + return true; // if status is "Approved" allow user to view the object + } + } + + return false; // do not allow user to view the object if no record found in assertion table, or if status is anything other than "Approved" + } + + private Dataset loadDataset(String id) { + return datasetRepository.findByIdWithTagsAndVisas(id).orElseThrow(() -> new ResourceNotFoundException("No Dataset with ID: " + id)); + } + private DatasetResponseDTO convertToResponseDto(Dataset dataset, PassportUserVisaAssertion assertion) { // prepare tags Set tagDtos = dataset.getTags() diff --git a/src/main/java/org/ga4gh/refcloud/api/core/dataset/ManifestResponseDTO.java b/src/main/java/org/ga4gh/refcloud/api/core/dataset/ManifestResponseDTO.java new file mode 100644 index 00000000..e4e51a4b --- /dev/null +++ b/src/main/java/org/ga4gh/refcloud/api/core/dataset/ManifestResponseDTO.java @@ -0,0 +1,20 @@ +package org.ga4gh.refcloud.api.core.dataset; + +import java.time.LocalDateTime; +import java.util.Map; +import tools.jackson.databind.PropertyNamingStrategies; +import tools.jackson.databind.annotation.JsonNaming; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public record ManifestResponseDTO( + String id, + String name, + Long size, + LocalDateTime created, + LocalDateTime updated, + String version, + String mimeType, + String description, + Boolean isManifest, + Map manifestContent +) {} diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/DrsConfig.java b/src/main/java/org/ga4gh/refcloud/api/drs/DrsConfig.java index 14697eed..a690adde 100644 --- a/src/main/java/org/ga4gh/refcloud/api/drs/DrsConfig.java +++ b/src/main/java/org/ga4gh/refcloud/api/drs/DrsConfig.java @@ -5,6 +5,7 @@ @ConfigurationProperties(prefix = "ga4gh.refcloud.drs") public record DrsConfig( + String scheme, String hostDomain, ServiceInfo serviceInfo ){ diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessMethodResponseDTO.java b/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessMethodResponseDTO.java index 6290df58..820b8cc8 100644 --- a/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessMethodResponseDTO.java +++ b/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessMethodResponseDTO.java @@ -1,12 +1,15 @@ package org.ga4gh.refcloud.api.drs.accessmethod; +import com.fasterxml.jackson.annotation.JsonInclude; + import tools.jackson.databind.PropertyNamingStrategies; import tools.jackson.databind.annotation.JsonNaming; @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@JsonInclude(JsonInclude.Include.NON_NULL) public record AccessMethodResponseDTO( AccessMethodType type, - String accessUrl, + AccessUrlResponseDTO accessUrl, String cloud, String region, boolean available diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessUrlResponseDTO.java b/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessUrlResponseDTO.java new file mode 100644 index 00000000..88ae1f19 --- /dev/null +++ b/src/main/java/org/ga4gh/refcloud/api/drs/accessmethod/AccessUrlResponseDTO.java @@ -0,0 +1,11 @@ +package org.ga4gh.refcloud.api.drs.accessmethod; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public record AccessUrlResponseDTO( + String url, + List headers +) {} diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObject.java b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObject.java index a757254c..d63c2be8 100644 --- a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObject.java +++ b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObject.java @@ -2,12 +2,16 @@ import java.time.LocalDateTime; import java.util.HashSet; +import java.util.Map; import java.util.Set; import org.ga4gh.refcloud.api.core.dataset.Dataset; import org.ga4gh.refcloud.api.drs.awss3accessobject.AwsS3AccessObject; import org.ga4gh.refcloud.api.drs.drsobjectalias.DrsObjectAlias; import org.ga4gh.refcloud.api.drs.drsobjectchecksum.DrsObjectChecksum; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.Id; @@ -20,6 +24,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import tools.jackson.databind.JsonNode; @Entity @Table(name = "drs_object") @@ -47,6 +52,12 @@ public class DrsObject { private String description; + private Boolean isManifest; + + @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "manifest_content", columnDefinition = "jsonb") + private Map manifestContent; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "dataset_id", nullable = false) private Dataset dataset; diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectPublicController.java b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectPublicController.java index 50a32fbf..f81f82b0 100644 --- a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectPublicController.java +++ b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectPublicController.java @@ -1,5 +1,7 @@ package org.ga4gh.refcloud.api.drs.drsobject; +import java.util.Map; + import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectAuthInfoRequestDTO; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectAuthInfoResponseDTO; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectRequestDTO; @@ -45,8 +47,8 @@ public ResponseEntity getDrsObjectByIdPostMethod(@PathVari return ResponseEntity.ok(drsObjectService.getDrsObjectById(id)); } - @PreAuthorize("@GA4GHPassportTokenEvaluator.validateBulkAuthInfoRequest(authentication, #requestBody)") @RequestMapping(method=RequestMethod.OPTIONS) + @PreAuthorize("@GA4GHPassportTokenEvaluator.validateBulkAuthInfoRequest(authentication, #requestBody)") public ResponseEntity getMultipleDrsObjectsAuthInfo(@Valid @RequestBody MultiDrsObjectAuthInfoRequestDTO requestBody) { return ResponseEntity.ok(drsObjectService.getMultiDrsObjectsAuthInfo(requestBody.bulkObjectIds())); } @@ -56,4 +58,11 @@ public ResponseEntity getMultipleDrsObjectsAu public ResponseEntity getMultipleDrsObjects(@Valid @RequestBody MultiDrsObjectRequestDTO requestBody) { return ResponseEntity.ok(drsObjectService.getMultiDrsObjects(requestBody.passports(), requestBody.bulkObjectIds())); } + + @GetMapping("/{id}/manifest-content") + @PreAuthorize("@GA4GHPassportTokenEvaluator.canAccessDrsObject(authentication, #id)") + public ResponseEntity> getDrsObjectManifestContent(@PathVariable String id) { + Map manifestContent = drsObjectService.getDrsObjectManifestContent(id); + return ResponseEntity.ok(manifestContent); + } } diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectRepository.java b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectRepository.java index f5bc583a..d870bf9d 100644 --- a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectRepository.java +++ b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectRepository.java @@ -1,9 +1,16 @@ package org.ga4gh.refcloud.api.drs.drsobject; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface DrsObjectRepository extends JpaRepository { + @Query("SELECT d FROM DrsObject d WHERE d.dataset.id = :datasetId AND d.isManifest = true") + Page findDrsObjectManifestsByDatasetId(@Param("datasetId") String datasetId, Pageable pageable); + } diff --git a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectService.java b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectService.java index 65d7af6d..d6996b89 100644 --- a/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectService.java +++ b/src/main/java/org/ga4gh/refcloud/api/drs/drsobject/DrsObjectService.java @@ -2,12 +2,14 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.ga4gh.refcloud.api.drs.DrsConfig; import org.ga4gh.refcloud.api.drs.accessmethod.AccessMethodResponseDTO; import org.ga4gh.refcloud.api.drs.accessmethod.AccessMethodType; +import org.ga4gh.refcloud.api.drs.accessmethod.AccessUrlResponseDTO; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectAuthInfoResponseDTO; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectAuthInfoSummaryResponseDTO; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectAuthInfoUnresolvedIdSetResponseDTO; @@ -176,6 +178,15 @@ public boolean bulkRequestWithinLimit(List bulkObjectIds) { return bulkObjectIds.size() <= drsConfig.serviceInfo().drs().maxBulkLengthRequest(); } + @Transactional(readOnly = true) + public Map getDrsObjectManifestContent(String drsObjectId) { + DrsObject drsObject = loadDrsObject(drsObjectId); + if (!drsObject.getIsManifest()) { + throw new ResourceNotFoundException("DRS Object with ID: " + drsObjectId + " is not a manifest"); + } + return drsObject.getManifestContent(); + } + @Transactional(readOnly = true) private Boolean requireDrsObjectExists(String id) { boolean exists = drsObjectRepository.existsById(id); @@ -196,16 +207,38 @@ private DrsObjectResponseDTO convertToResponseDTO(DrsObject drsObject) { .map(checksum -> new DrsObjectChecksumResponseDTO(checksum.getChecksum(), checksum.getType())) .collect(Collectors.toSet()); - Set accessMethodDtos = drsObject.getAwsS3AccessObjects() + Set accessMethodDtos; + + if (drsObject.getIsManifest() == true) { // manifests - raw content stored as JSON in DB + + accessMethodDtos = null; + accessMethodDtos = Set.of( + new AccessMethodResponseDTO( + AccessMethodType.https, + new AccessUrlResponseDTO( + generateAccessUrlForManifestObject(drsObject.getId()), + null + ), + null, + null, + true + ) + ); + } else { // AWS objects - raw content stored in S3 + accessMethodDtos = drsObject.getAwsS3AccessObjects() .stream() .map(s3Object -> new AccessMethodResponseDTO( AccessMethodType.https, - generateAccessUrlForOpenAccessS3Object(s3Object), + new AccessUrlResponseDTO( + generateAccessUrlForOpenAccessS3Object(s3Object), + null + ), "aws", s3Object.getRegion(), true )) .collect(Collectors.toSet()); + } Set aliasDtos = drsObject.getAliases() .stream() @@ -242,6 +275,15 @@ private String generateAccessUrlForOpenAccessS3Object(AwsS3AccessObject awsS3Acc awsS3AccessObject.getKey(); } + private String generateAccessUrlForManifestObject(String id) { + return drsConfig.scheme() + + "://" + + drsConfig.hostDomain() + + "/ga4gh/drs/v1/objects/" + + id + + "/manifest-content"; + } + private SingleDrsObjectAuthInfoResponseDTO generateAuthInfoForSingleDrsObjectId(String id) { return new SingleDrsObjectAuthInfoResponseDTO( id, diff --git a/src/main/java/org/ga4gh/refcloud/api/security/GA4GHPassportTokenEvaluator.java b/src/main/java/org/ga4gh/refcloud/api/security/GA4GHPassportTokenEvaluator.java index 3f3486cb..c58eb051 100644 --- a/src/main/java/org/ga4gh/refcloud/api/security/GA4GHPassportTokenEvaluator.java +++ b/src/main/java/org/ga4gh/refcloud/api/security/GA4GHPassportTokenEvaluator.java @@ -1,6 +1,7 @@ package org.ga4gh.refcloud.api.security; import org.springframework.stereotype.Component; +import org.ga4gh.refcloud.api.core.dataset.DatasetService; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectAuthInfoRequestDTO; import org.ga4gh.refcloud.api.drs.authinfo.MultiDrsObjectRequestDTO; import org.ga4gh.refcloud.api.drs.authinfo.SingleDrsObjectRequestDTO; @@ -19,13 +20,24 @@ public class GA4GHPassportTokenEvaluator { private final DrsObjectService drsObjectService; - public GA4GHPassportTokenEvaluator(JwtDecoder jwtDecoder, DrsObjectService drsObjectService) { + private final DatasetService datasetService; + + public GA4GHPassportTokenEvaluator(JwtDecoder jwtDecoder, DrsObjectService drsObjectService, DatasetService datasetService) { this.jwtDecoder = jwtDecoder; this.drsObjectService = drsObjectService; + this.datasetService = datasetService; + } + + public boolean canAccessDataset(Authentication authentication, String datasetId) { + if (authentication == null || !(authentication.getPrincipal() instanceof Jwt jwt)) { + return false; + } + + String userId = jwt.getSubject(); + return datasetService.validateUserIsAuthorizedForDataset(userId, datasetId); } public boolean canAccessDrsObject(Authentication authentication, String objectId) { - // Sanity check the authentication context if (authentication == null || !(authentication.getPrincipal() instanceof Jwt jwt)) { return false; } diff --git a/src/main/java/org/ga4gh/refcloud/api/security/SecurityConfig.java b/src/main/java/org/ga4gh/refcloud/api/security/SecurityConfig.java index 2ece8e98..143704ae 100644 --- a/src/main/java/org/ga4gh/refcloud/api/security/SecurityConfig.java +++ b/src/main/java/org/ga4gh/refcloud/api/security/SecurityConfig.java @@ -23,14 +23,20 @@ public class SecurityConfig { private final OrySessionFilter orySessionFilter; + private static final List ORY_KRATOS_SESSION_ENDPOINTS = List.of( + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/datasets"), + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/datasets/{datasetId}"), + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/datasets/{datasetId}/request-access") + ); + private static final List PUBLIC_ENDPOINTS = List.of( - // DRS API PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.OPTIONS, "/ga4gh/drs/v1/objects/{id}"), PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/ga4gh/drs/v1/service-info") ); private static final List CUSTOM_SECURITY_ENDPOINTS = List.of( - // DRS API + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/datasets/{datasetId}/manifests"), + PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.GET, "/ga4gh/drs/v1/objects/{id}"), PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/ga4gh/drs/v1/objects/{id}"), PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.OPTIONS, "/ga4gh/drs/v1/objects"), PathPatternRequestMatcher.withDefaults().matcher(HttpMethod.POST, "/ga4gh/drs/v1/objects") @@ -61,7 +67,7 @@ public SecurityFilterChain oryKratosSessionFilterChain(HttpSecurity http) throws // Disable standard CSRF/sessions since we are an API validated by Ory Kratos tokens .csrf(csrf -> csrf.disable()) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .securityMatcher("/datasets/**") + .securityMatcher(new OrRequestMatcher(ORY_KRATOS_SESSION_ENDPOINTS)) .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() // endpoints that require kratos session token ) @@ -92,6 +98,7 @@ public SecurityFilterChain customSecurityEndpointsFilterChain(HttpSecurity http) .authorizeHttpRequests(authorize -> authorize .anyRequest().permitAll() ) + .oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> {})) .csrf(csrf -> csrf.disable()) .sessionManagement(session -> session.disable()); diff --git a/src/main/java/org/ga4gh/refcloud/api/utils/HibernateJackson3BridgeConfig.java b/src/main/java/org/ga4gh/refcloud/api/utils/HibernateJackson3BridgeConfig.java new file mode 100644 index 00000000..ad64efb3 --- /dev/null +++ b/src/main/java/org/ga4gh/refcloud/api/utils/HibernateJackson3BridgeConfig.java @@ -0,0 +1,37 @@ +package org.ga4gh.refcloud.api.utils; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.type.descriptor.java.JavaType; +import org.hibernate.type.format.FormatMapper; +import org.hibernate.type.descriptor.WrapperOptions; +import org.springframework.boot.hibernate.autoconfigure.HibernatePropertiesCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +// Make sure your ObjectMapper import matches your active Jackson 3 package +// Typically: import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; + +@Configuration +public class HibernateJackson3BridgeConfig { + + @Bean + public HibernatePropertiesCustomizer jsonFormatMapperCustomizer(ObjectMapper objectMapper) { + return hibernateProperties -> + hibernateProperties.put(AvailableSettings.JSON_FORMAT_MAPPER, new FormatMapper() { + + @Override + public T fromString(CharSequence charSequence, JavaType javaType, WrapperOptions wrapperOptions) { + // Bridge Hibernate's JavaType to Jackson 3's TypeFactory layout + var jacksonType = objectMapper.getTypeFactory().constructType(javaType.getJavaType()); + return objectMapper.readValue(charSequence.toString(), jacksonType); + } + + @Override + public String toString(T value, JavaType javaType, WrapperOptions wrapperOptions) { + // Serialize the object safely to string using Jackson 3 + return objectMapper.writeValueAsString(value); + } + }); + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 45a0f0bf..04c9bfa4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -43,7 +43,8 @@ ga4gh: username: kratos_webhook_user password: secret drs: - host-domain: localhost:8080 + scheme: http + host-domain: 127.0.0.1:8080 service-info: id: org.ga4gh.refcloud.drs.local name: GA4GH Reference Cloud DRS Service (Local Dev Environment) diff --git a/src/test/resources/sql/add-test-data.sql b/src/test/resources/sql/add-test-data.sql index 99ae9aaf..8cc62a4d 100644 --- a/src/test/resources/sql/add-test-data.sql +++ b/src/test/resources/sql/add-test-data.sql @@ -80,16 +80,57 @@ INSERT INTO passport_visa (id, name, description, dataset_id) VALUES INSERT INTO drs_object (id, description, created_time, mime_type, name, size, updated_time, version, dataset_id) VALUES - ('drs.id.0', '1000 Genomes Phase3 WGS alignment BAM: HG00096 chr11', '2015-05-13 03:10:08', 'application/x-bam', 'HG00096.chrom11.ILLUMINA.bwa.GBR.low_coverage.20120522.bam', 692760649, '2015-05-13 03:10:08', 'v1', 'ds1'); + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', 'HG00096 whole-exome bam file', '2015-05-13 03:30:44', 'application/octet-stream', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', 9196950908, '2015-05-13 03:30:44', 'v1', 'ds1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', 'HG00096 whole-exome bai file', '2015-05-13 03:12:41', 'application/octet-stream', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', 6842584, '2015-05-13 03:12:41', 'v1', 'ds1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 'HG00096 whole-exome bas file', '2015-05-13 03:29:43', 'application/octet-stream', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 827, '2015-05-13 03:29:43', 'v1', 'ds1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', 'HG00096 whole-exome cram file', '2015-05-13 03:13:58', 'application/octet-stream', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', 2304099249, '2015-05-13 03:13:58', 'v1', 'ds1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', 'HG00096 whole-exome crai file', '2015-05-13 03:27:40', 'application/octet-stream', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', 178859, '2015-05-13 03:27:40', 'v1', 'ds1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', 'HG00096 whole-exome csra file', '2015-05-13 03:14:58', 'application/octet-stream', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', 2282395745, '2015-05-13 03:14:58', 'v1', 'ds1'); INSERT INTO drs_object_alias (drs_object_id, alias) VALUES - ('drs.id.0', 'HG00096 chr11 BAM'), - ('drs.id.0', 'HG00096 chr11 BAM file'); + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', 'HG00096 whole-exome bam file'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', 'HG00096 whole-exome bai file'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 'HG00096 whole-exome bas file'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', 'HG00096 whole-exome cram file'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', 'HG00096 whole-exome crai file'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', 'HG00096 whole-exome csra file'); INSERT INTO drs_object_checksum(drs_object_id, checksum, type) VALUES - ('drs.id.0', 'e2425c6f57b2aa4ddb08f472d98221d0', 'md5'), - ('drs.id.0', '9dddead4e1b13471784e536824ffed3c6137126a', 'sha1'), - ('drs.id.0', '718f74b48fd739c9305bbf6c3d4b29ef3c9d62fcb1c16eaae61dbfd0c5db60d5', 'sha256'); + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', '5d4ae7a46d470036d99429c363498965', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', '72d9fc6f08feb87b5e9666eb6bee98bd00b0d024', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', 'e2062842263d1ca42ce4368e61850b75a58f34cd9b6347c465ea95e3da31d943', 'sha256'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', 'a8a1f1ba420f7d75c7955b04b5972c54', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', '56e7a1d55713e74eccf220365bbeec69ced899ad', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', '89d6677f9e8d54fd3d771177ab352fb5d7435cf4ad1fb5dec33e5a508612f5c0', 'sha256'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 'e2ebae06af6ce9c92750339e9a85e5d9', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 'a3327258093db7eea317b41dff596a032e7e27cf', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 'fb028f0d383e9cc8e987c287a263191c9f910963dc4ad0c68094d569ba714033', 'sha256'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', '46d0f8f93809c608571d82c327bb8bfc', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', 'bbc73bcee7a1e837d5541db1857611b75288a53f', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', '5b8da495309e4b1a2fa229557a2f4ccb7be9347b75fac6c37bc845cb0dcf0784', 'sha256'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', '83ef6855b01965759b9c3c9c7e6586a8', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', 'b7d52204789cc5e098a6be807083165a8a34f4f6', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', '722260f9c8757ed603cfb1bf7441e076371028c05e3f89a81930c895254837ee', 'sha256'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', '35e12569cd5dacb4d158832bedfb8b1b', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', '8f1f9634ab8118717471420a5703fb10ee5383b6', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', 'd5b7a372c4c0187590b3a73b4fd79a4913ad1900305694cb2a33051e63684e89', 'sha256'); INSERT INTO aws_s3_access_object(drs_object_id, region, bucket, key) VALUES - ('drs.id.0', 'us-east-1', '1000genomes', '/phase3/data/HG00096/alignment/HG00096.chrom11.ILLUMINA.bwa.GBR.low_coverage.20120522.bam'); + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam', 'us-east-1', '1000genomes', '/phase3/data/HG00096/exome_alignment/HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai', 'us-east-1', '1000genomes', '/phase3/data/HG00096/exome_alignment/HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas', 'us-east-1', '1000genomes', '/phase3/data/HG00096/exome_alignment/HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram', 'us-east-1', '1000genomes', '/phase3/data/HG00096/exome_alignment/HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai', 'us-east-1', '1000genomes', '/phase3/data/HG00096/exome_alignment/HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra', 'us-east-1', '1000genomes', '/phase3/data/HG00096/exome_alignment/HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra'); + +/* DRS Object Manifest */ +INSERT INTO drs_object (id, description, created_time, mime_type, name, size, updated_time, version, dataset_id, is_manifest, manifest_content) VALUES + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.MANIFEST', 'HG00096 whole-exome - compound object manifest', '2015-05-13 03:30:44', 'application/json', 'HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.MANIFEST', 416, '2015-05-13 03:30:44', 'v1', 'ds1', true, '{"bam_file":"HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam","bai_file":"HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bai","bas_file":"HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.bas","cram_file":"HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram","crai_file":"HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.cram.crai","csra_file":"HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.bam.csra"}'); + +INSERT INTO drs_object_alias (drs_object_id, alias) VALUES + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.MANIFEST', 'HG00096 whole-exome - compound object manifest'); + +INSERT INTO drs_object_checksum(drs_object_id, checksum, type) VALUES + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.MANIFEST', 'f257d781e1d4017d1a851b61acc7e93c', 'md5'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.MANIFEST', 'f9db5b1a3332972dbe499399543f210b88dbe55c', 'sha1'), + ('HG00096.mapped.ILLUMINA.bwa.GBR.exome.20120522.MANIFEST', 'e5a3e248d68a035d23e2ed336c93aaf78cd46aceca7cd814e58689896f97b33c', 'sha256'); \ No newline at end of file