diff --git a/.idea/copyright/copyright.xml b/.idea/copyright/copyright.xml deleted file mode 100644 index 9a47cbe2a..000000000 --- a/.idea/copyright/copyright.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6a04acd55..f7b14775f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,39 +6,34 @@ portal com.odysseusinc.arachne - 1.17.1 + 1.18.0 jar org.springframework.boot spring-boot-starter-parent - 1.5.22.RELEASE + 2.1.18.RELEASE - 1.5.22.RELEASE + 2.1.18.RELEASE com.odysseusinc.arachne.portal.PortalStarter UTF-8 1.8 0.10.8 5.15.14 - 3.13.2 + 3.19.0 ${BUILD_TIMESTAMP} ${BUILD_NUMBER} 2.0.1 1.4 - 2.8.0 - 3.11 1.7 hub.odysseusinc.com 1.3.0 2.7 - 5.2.12.Final - 2.6.3 - 2.10.5.20201202 - 4.2.0 - 42.2.15 + 4.3.0 + 42.2.19 1.2.4.RELEASE 1.68 @@ -97,26 +92,11 @@ - - org.thymeleaf - thymeleaf - 3.0.6.RELEASE - - - org.thymeleaf - thymeleaf-spring4 - 3.0.6.RELEASE - solr-solrj org.apache.solr 7.7.3 - - org.flywaydb - flyway-core - 4.2.0 - org.ohdsi authenticator @@ -125,7 +105,6 @@ commons-io commons-io - ${commons.io.version} @@ -159,12 +138,6 @@ arachne-sys-settings com.odysseusinc.arachne ${project.version} - - - org.flywaydb - flyway-core - - com.odysseusinc.arachne @@ -175,32 +148,26 @@ org.springframework.boot spring-boot-starter-web - ${spring.boot.version} org.springframework.boot spring-boot-starter-security - ${spring.boot.version} org.springframework.boot spring-boot-starter-logging - ${spring.boot.version} org.springframework.boot spring-boot-starter-data-jpa - ${spring.boot.version} org.springframework.boot spring-boot-starter-mail - ${spring.boot.version} org.springframework.boot spring-boot-starter-test - ${spring.boot.version} org.assertj @@ -211,7 +178,6 @@ org.springframework.boot spring-boot-starter-websocket - ${spring.boot.version} org.springframework.security @@ -221,12 +187,15 @@ org.springframework.security spring-security-test - org.postgresql postgresql ${postgresql.version} + + org.flywaydb + flyway-core + com.google.code.gson gson @@ -235,7 +204,6 @@ org.apache.commons commons-lang3 - ${commons.lang3.version} io.jsonwebtoken @@ -290,12 +258,8 @@ org.apache.solr - org.thymeleaf - thymeleaf - - - org.thymeleaf - thymeleaf-spring4 + org.springframework.boot + spring-boot-starter-thymeleaf @@ -315,17 +279,12 @@ commons-beanutils commons-beanutils + 1.9.4 - - com.zaxxer - HikariCP - ${hikaricp.version} - - - + org.dbunit dbunit - 2.5.3 + 2.7.0 jar test @@ -365,7 +324,7 @@ com.cosium.spring.data spring-data-jpa-entity-graph - 1.11.03 + 2.1.0 org.jodconverter @@ -473,6 +432,7 @@ spring-boot-maven-plugin + repackage repackage @@ -485,7 +445,7 @@ com.spotify docker-maven-plugin - 1.0.0 + 1.2.2 ${dockerImagePrefix}/${project.artifactId} @@ -566,8 +526,8 @@ - odysseus.community.snapshots - Odysseus community snapshots + community-libs-snapshot-local + community-libs-snapshot-local false always @@ -576,11 +536,11 @@ true always - http://repo.odysseusinc.com/artifactory/community-libs-snapshot-local + https://nexus.odysseusinc.com/repository/community-libs-snapshot-local - odysseus.community.releases - Odysseus community releases + community-libs-release-local + community-libs-release-local true always @@ -589,7 +549,7 @@ false always - http://repo.odysseusinc.com/artifactory/community-libs-release-local + https://nexus.odysseusinc.com/repository/community-libs-release-local ohdsi @@ -616,14 +576,14 @@ - artifactory - Odysseus community snapshots - http://repo.odysseusinc.com/artifactory/community-libs-snapshot-local + community-libs-snapshot-local + community-libs-snapshot-local + https://nexus.odysseusinc.com/repository/community-libs-snapshot-local - artifactory - Odysseus community releases - http://repo.odysseusinc.com/artifactory/community-libs-release-local + community-libs-release-local + community-libs-release-local + https://nexus.odysseusinc.com/repository/community-libs-release-local diff --git a/src/main/java/com/odysseusinc/arachne/portal/PortalStarter.java b/src/main/java/com/odysseusinc/arachne/portal/PortalStarter.java index 605c38533..cae330d05 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/PortalStarter.java +++ b/src/main/java/com/odysseusinc/arachne/portal/PortalStarter.java @@ -24,6 +24,7 @@ import com.cosium.spring.data.jpa.entity.graph.repository.support.EntityGraphJpaRepositoryFactoryBean; import com.odysseusinc.arachne.system.settings.config.SpringPropertiesConfig; +import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.domain.EntityScan; @@ -34,13 +35,13 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.jms.annotation.EnableJms; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; @Configuration @ComponentScan( basePackages = {"com.odysseusinc.arachne.*", "org.ohdsi.authenticator.*"}, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.odysseusinc.arachne.system.settings.config.SpringPropertiesConfig") ) - @EnableAutoConfiguration @EnableScheduling @EnableJpaRepositories( @@ -48,6 +49,7 @@ basePackages = {"com.odysseusinc.arachne.*"} ) @EnableAspectJAutoProxy +@EnableEncryptableProperties @EnableJms @EntityScan(basePackages = {"com.odysseusinc.arachne.*"}) public class PortalStarter { diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAchillesController.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAchillesController.java index b00166a8c..79e8fa54c 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAchillesController.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAchillesController.java @@ -193,7 +193,7 @@ public ResponseEntity> listReports() throws NotExi protected DS checkDataSource(Long datasourceId) throws NotExistException { - DS dataSource = rawDataSourceRepository.findOne(datasourceId); + DS dataSource = rawDataSourceRepository.getOne(datasourceId); if (dataSource == null) { String message = String.format("Datasource with id: '%s' not found", datasourceId); throw new NotExistException(message, dataSourceClass); diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAdminController.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAdminController.java index a3ee4f24e..093166b54 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAdminController.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAdminController.java @@ -179,7 +179,7 @@ public Page getAll( final Page users = userService.getPage(pageable, userSearch); final DeletableUserWithTenantsListDTO userDtoList = conversionService.convert(users.getContent(), DeletableUserWithTenantsListDTO.class); - return new CustomPageImpl<>(userDtoList, new PageRequest(pageable.getPageNumber() - 1, pageable.getPageSize()), users.getTotalElements()); + return new CustomPageImpl<>(userDtoList, PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize()), users.getTotalElements()); } @ApiOperation("Register new users") diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAnalysisController.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAnalysisController.java index cdfae2979..d22983c23 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAnalysisController.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseAnalysisController.java @@ -459,7 +459,7 @@ public JsonResult getSubmissionInsight( } final SubmissionInsight insight = submissionInsightService.getSubmissionInsight(submissionId); final SubmissionInsightDTO insightDTO = conversionService.convert(insight, SubmissionInsightDTO.class); - final Set recentTopics = submissionInsightService.getInsightComments(insight, size, new Sort(order, "id")); + final Set recentTopics = submissionInsightService.getInsightComments(insight, size, Sort.by(order, "id")); final List recentCommentables = getRecentCommentables(conversionService, recentTopics, insightDTO); insightDTO.setRecentCommentEntities(recentCommentables); final JsonResult result = new JsonResult<>(NO_ERROR); diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseStudyController.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseStudyController.java index a5b0f1298..45cf32f83 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseStudyController.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/BaseStudyController.java @@ -669,13 +669,13 @@ public List getStudyInsights( List submissionInsightDTOS = new ArrayList<>(); - Pageable pageRequest = new PageRequest(0, size, new Sort(order, "created")); + Pageable pageRequest = PageRequest.of(0, size, Sort.by(order, "created")); final Page page = submissionInsightService.getInsightsByStudyId(studyId, pageRequest); final List insights = page.getContent(); for (int i = 0; i < insights.size(); i++) { final SubmissionInsight insight = insights.get(i); final Set recentTopics = submissionInsightService.getInsightComments(insight, - commentsPerInsight, new Sort(Sort.Direction.DESC, "id")); + commentsPerInsight, Sort.by(Sort.Direction.DESC, "id")); final SubmissionInsightDTO insightDTO = conversionService.convert(insight, SubmissionInsightDTO.class); final List recentCommentables = getRecentCommentables(conversionService, recentTopics, insightDTO); diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/submission/BaseSubmissionController.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/submission/BaseSubmissionController.java index 932fef704..503764a07 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/submission/BaseSubmissionController.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/controller/submission/BaseSubmissionController.java @@ -284,16 +284,17 @@ public void downloadAllSubmissionResultFiles( @PathVariable("submissionId") Long submissionId, HttpServletResponse response) throws PermissionDeniedException, NotExistException, IOException { - String archiveName = "submission_result_" + submissionId + "_" - + System.currentTimeMillis() - + ".zip"; + final Submission submission = submissionService.getSubmissionById(submissionId); + final String analysisTypeCode = submission.getSubmissionGroup().getAnalysis().getType().getCode(); + final String archiveName = String.format("%s_submission_result_%s_%s.zip", analysisTypeCode, submissionId, + System.currentTimeMillis()); + String contentType = "application/zip, application/octet-stream"; response.setContentType(contentType); response.setHeader("Content-type", contentType); response.setHeader("Content-Disposition", "attachment; filename=" + archiveName); - Submission submission = submissionService.getSubmissionById(submissionId); IUser user = userService.getByUsername(principal.getName()); submissionService .getSubmissionResultAllFiles(user, submission.getSubmissionGroup().getAnalysis().getId(), diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CommonStudyDTO.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CommonStudyDTO.java index 72d04689a..c3c3fb87a 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CommonStudyDTO.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CommonStudyDTO.java @@ -22,6 +22,7 @@ package com.odysseusinc.arachne.portal.api.v1.dto; +import com.odysseusinc.arachne.portal.api.v1.dto.converters.study.StudyTitle; import com.odysseusinc.arachne.portal.model.StudyKind; import java.util.LinkedList; import java.util.List; @@ -29,6 +30,7 @@ public class CommonStudyDTO { public Long id; + @StudyTitle private String title; private List dataSources = new LinkedList<>(); diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CreateStudyDTO.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CreateStudyDTO.java index 9d83b12c3..cf45ea7ee 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CreateStudyDTO.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/CreateStudyDTO.java @@ -22,20 +22,15 @@ package com.odysseusinc.arachne.portal.api.v1.dto; +import com.odysseusinc.arachne.portal.api.v1.dto.converters.study.StudyTitle; import javax.validation.constraints.NotNull; -import org.hibernate.validator.constraints.Length; -import org.hibernate.validator.constraints.NotBlank; /** * Created by AKrutov on 07.11.2016. */ public class CreateStudyDTO { - @NotBlank - @Length.List({ - @Length(min = 5, message = "The field must be at least 5 characters"), - @Length(max = 1000, message = "The field must be less than 255 characters") - }) + @StudyTitle private String title; @NotNull(message = "Study type should be defined") diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/DataSourceDTO.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/DataSourceDTO.java index fb56a55a9..741b3407b 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/DataSourceDTO.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/DataSourceDTO.java @@ -24,7 +24,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.odysseusinc.arachne.commons.api.v1.dto.CommonBaseDataSourceDTO; +import com.odysseusinc.arachne.commons.api.v1.dto.CommonDataSourceAccessType; import com.odysseusinc.arachne.commons.api.v1.dto.CommonHealthStatus; + import java.util.Date; @JsonInclude(JsonInclude.Include.NON_NULL) @@ -36,6 +38,7 @@ public class DataSourceDTO extends CommonBaseDataSourceDTO implements IDataSourc private String healthStatusTitle; private Date deleted; private PermissionsDTO permissions; + private CommonDataSourceAccessType accessType; private boolean canBeRecreated = Boolean.TRUE; public String getStatus() { @@ -107,4 +110,14 @@ public void setCanBeRecreated(final boolean canBeRecreated) { this.canBeRecreated = canBeRecreated; } + + @Override + public CommonDataSourceAccessType getAccessType() { + return accessType; + } + + @Override + public void setAccessType(CommonDataSourceAccessType accessType) { + this.accessType = accessType; + } } diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/SearchResultToFacetedSearchResultDTOConverter.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/SearchResultToFacetedSearchResultDTOConverter.java index ae02adf60..703813a94 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/SearchResultToFacetedSearchResultDTOConverter.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/SearchResultToFacetedSearchResultDTOConverter.java @@ -113,7 +113,7 @@ protected PageRequest buildPageRequest(SearchResult source) { if (source.getSolrQuery().getStart() > 0) { pageNum += (source.getSolrQuery().getStart() / source.getSolrQuery().getRows()); } - return new PageRequest(pageNum, itemsOnPage); + return PageRequest.of(pageNum, itemsOnPage); } protected long getTotal(SearchResult source) { diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceDTOToDataSourceConverter.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceDTOToDataSourceConverter.java index 8ade1a91d..e6fccf15b 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceDTOToDataSourceConverter.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceDTOToDataSourceConverter.java @@ -42,6 +42,7 @@ public final DS convert(DTO source) { dataSource.setCdmVersion(source.getCdmVersion()); dataSource.setPublished(source.getPublished()); dataSource.setDbmsType(source.getDbmsType()); + dataSource.setAccessType(source.getAccessType()); proceedAdditionalFields(dataSource, source); diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceToCommonDataSourceDTOConverter.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceToCommonDataSourceDTOConverter.java index 4ef0553aa..0a89d3c2b 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceToCommonDataSourceDTOConverter.java +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/datasource/BaseDataSourceToCommonDataSourceDTOConverter.java @@ -45,6 +45,8 @@ public DTO convert(DS dataSource) { proceedAdditionalFields(commonDataSourceDTO, dataSource); commonDataSourceDTO.setPublished(dataSource.getPublished()); commonDataSourceDTO.setDbmsType(dataSource.getDbmsType()); + commonDataSourceDTO.setAccessType(dataSource.getAccessType()); + return commonDataSourceDTO; } diff --git a/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/study/StudyTitle.java b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/study/StudyTitle.java new file mode 100644 index 000000000..c8bb3d911 --- /dev/null +++ b/src/main/java/com/odysseusinc/arachne/portal/api/v1/dto/converters/study/StudyTitle.java @@ -0,0 +1,30 @@ +package com.odysseusinc.arachne.portal.api.v1.dto.converters.study; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.validation.Constraint; +import javax.validation.Payload; +import javax.validation.constraints.Pattern; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.Length.List; + +@Documented +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) +@Retention(RetentionPolicy.RUNTIME) +@List({ + @Length(min = 5, message = "The field must be at least 5 characters"), + @Length(max = 1000, message = "The field must be no more than 1000 characters") +}) +// Don't allow leading or trailing whitespace +@Pattern(regexp = "^\\S+(\\s+\\S+)*$", message = "Leading and trailing spaces are not allowed in the study title") +@Constraint(validatedBy = {}) +public @interface StudyTitle { + String message() default "{com.odysseusinc.arachne.portal.validation.Regex.message}"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/src/main/java/com/odysseusinc/arachne/portal/config/FlywayConfig.java b/src/main/java/com/odysseusinc/arachne/portal/config/FlywayConfig.java deleted file mode 100644 index 9c1d002b5..000000000 --- a/src/main/java/com/odysseusinc/arachne/portal/config/FlywayConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright 2018 Odysseus Data Services, inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Company: Odysseus Data Services, Inc. - * Product Owner/Architecture: Gregory Klebanov - * Authors: Pavel Grafkin, Alexandr Ryabokon, Vitaly Koulakov, Anton Gackovka, Maria Pozhidaeva, Mikhail Mironov - * Created: October 11, 2016 - * - */ - -package com.odysseusinc.arachne.portal.config; - -import com.odysseusinc.arachne.commons.config.flyway.ApplicationContextAwareSpringJdbcMigrationResolver; -import org.flywaydb.core.Flyway; -import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.ApplicationContext; -import org.springframework.core.Ordered; - -@Configuration -@ComponentScan("org.springframework.boot.autoconfigure.flyway") -public class FlywayConfig { - - @Bean - public FlywayMigrationInitializer flywayInitializer(ApplicationContext context, Flyway flyway) { - - ApplicationContextAwareSpringJdbcMigrationResolver contextAwareResolver = new ApplicationContextAwareSpringJdbcMigrationResolver(context); - flyway.setResolvers(contextAwareResolver); - - FlywayMigrationInitializer flywayMigrationInitializer = new FlywayMigrationInitializer(flyway, null); - flywayMigrationInitializer.setOrder(Ordered.LOWEST_PRECEDENCE); - return flywayMigrationInitializer; - } -} diff --git a/src/main/java/com/odysseusinc/arachne/portal/config/ThymeleafConfig.java b/src/main/java/com/odysseusinc/arachne/portal/config/ThymeleafConfig.java index bd8d045c5..74d7bdfab 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/config/ThymeleafConfig.java +++ b/src/main/java/com/odysseusinc/arachne/portal/config/ThymeleafConfig.java @@ -28,8 +28,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.thymeleaf.spring4.SpringTemplateEngine; -import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; import org.thymeleaf.templateresolver.ITemplateResolver; diff --git a/src/main/java/com/odysseusinc/arachne/portal/config/WebSocketConfig.java b/src/main/java/com/odysseusinc/arachne/portal/config/WebSocketConfig.java index 81db63f52..89f2e8f8f 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/config/WebSocketConfig.java +++ b/src/main/java/com/odysseusinc/arachne/portal/config/WebSocketConfig.java @@ -24,8 +24,6 @@ import com.odysseusinc.arachne.portal.model.IUser; import com.odysseusinc.arachne.portal.service.BaseUserService; -import java.security.Principal; -import java.util.List; import org.ohdsi.authenticator.service.authentication.Authenticator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -38,43 +36,45 @@ import org.springframework.core.annotation.Order; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageType; import org.springframework.messaging.simp.config.ChannelRegistration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.messaging.simp.user.DefaultUserDestinationResolver; import org.springframework.messaging.simp.user.SimpUserRegistry; import org.springframework.messaging.simp.user.UserDestinationResolver; -import org.springframework.messaging.support.ChannelInterceptorAdapter; +import org.springframework.messaging.support.ChannelInterceptor; import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.web.socket.CloseStatus; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; import org.springframework.web.socket.messaging.DefaultSimpUserRegistry; import org.springframework.web.socket.messaging.SessionConnectedEvent; import org.springframework.web.socket.messaging.SessionDisconnectEvent; import org.springframework.web.socket.messaging.SessionSubscribeEvent; import org.springframework.web.socket.messaging.SessionUnsubscribeEvent; +import java.security.Principal; +import java.util.List; @Configuration @ComponentScan(basePackages = {"com.odysseusinc.arachne.portal.service", "com.odysseusinc.arachne.portal.security"}) @EnableWebSocketMessageBroker @Order(Ordered.HIGHEST_PRECEDENCE + 99) -public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Value("${arachne.token.header}") private String tokenHeader; - private BaseUserService userService; - private Authenticator authenticator; - private DefaultSimpUserRegistry userRegistry = new DefaultSimpUserRegistry(); - private DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userRegistry); + private final BaseUserService userService; + private final Authenticator authenticator; + private final DefaultSimpUserRegistry userRegistry = new DefaultSimpUserRegistry(); + private final DefaultUserDestinationResolver resolver = new DefaultUserDestinationResolver(userRegistry); @Autowired public WebSocketConfig(@Lazy BaseUserService userService, - Authenticator authenticator) { + Authenticator authenticator) { this.userService = userService; this.authenticator = authenticator; } @@ -91,7 +91,6 @@ public UserDestinationResolver userDestinationResolver() { return resolver; } - @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/queue", "/topic"); @@ -104,14 +103,14 @@ public void registerStompEndpoints(StompEndpointRegistry registry) { } @Override - public void configureClientInboundChannel(ChannelRegistration registration) { - registration.setInterceptors(new ChannelInterceptorAdapter() { + public void configureClientOutboundChannel(ChannelRegistration registration) { + registration.interceptors(new ChannelInterceptor() { @Override public Message preSend(Message message, MessageChannel channel) { - StompHeaderAccessor accessor = - MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); + SimpMessageHeaderAccessor accessor = + MessageHeaderAccessor.getAccessor(message, SimpMessageHeaderAccessor.class); Principal principal = null; @@ -154,9 +153,9 @@ public Message preSend(Message message, MessageChannel channel) { ) ); } - return message; } }); } } + diff --git a/src/main/java/com/odysseusinc/arachne/portal/config/tenancy/HibernateConfig.java b/src/main/java/com/odysseusinc/arachne/portal/config/tenancy/HibernateConfig.java index 26e987bfd..521a3ff23 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/config/tenancy/HibernateConfig.java +++ b/src/main/java/com/odysseusinc/arachne/portal/config/tenancy/HibernateConfig.java @@ -1,14 +1,34 @@ +/* + * + * Copyright 2018 Odysseus Data Services, inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Company: Odysseus Data Services, Inc. + * Product Owner/Architecture: Gregory Klebanov + * Authors: Alexandr Cumarav + * + */ + package com.odysseusinc.arachne.portal.config.tenancy; import com.odysseusinc.arachne.portal.config.interceptors.QueryInterceptor; -import java.util.HashMap; -import java.util.Map; -import javax.sql.DataSource; import org.hibernate.MultiTenancyStrategy; import org.hibernate.cfg.Environment; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,6 +36,9 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import javax.sql.DataSource; +import java.util.Map; + @Configuration public class HibernateConfig { @@ -24,7 +47,7 @@ public class HibernateConfig { @Autowired(required = false) private QueryInterceptor queryInterceptor; - + @Bean public JpaVendorAdapter jpaVendorAdapter() { @@ -34,10 +57,11 @@ public JpaVendorAdapter jpaVendorAdapter() { @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, MultiTenantConnectionProvider multiTenantConnectionProviderImpl, - CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) { + CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl, + HibernateProperties hibernateProperties) { - Map properties = new HashMap<>(); - properties.putAll(jpaProperties.getHibernateProperties(dataSource)); + Map properties = hibernateProperties.determineHibernateProperties( + jpaProperties.getProperties(), new HibernateSettings()); // NOTE: // dummy setting, just to force Hibernate to use custom connection provider through which we pass current tenant id to DB properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA); diff --git a/src/main/java/com/odysseusinc/arachne/portal/model/BaseDataSource.java b/src/main/java/com/odysseusinc/arachne/portal/model/BaseDataSource.java index 4197ec102..4156b095c 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/model/BaseDataSource.java +++ b/src/main/java/com/odysseusinc/arachne/portal/model/BaseDataSource.java @@ -22,6 +22,7 @@ package com.odysseusinc.arachne.portal.model; +import com.odysseusinc.arachne.commons.api.v1.dto.CommonDataSourceAccessType; import com.odysseusinc.arachne.commons.api.v1.dto.CommonHealthStatus; import com.odysseusinc.arachne.commons.api.v1.dto.CommonModelType; import com.odysseusinc.arachne.commons.types.CommonCDMVersionDTO; @@ -92,7 +93,7 @@ public abstract class BaseDataSource implements IDataSource, Serializable, HasAr @Enumerated(value = EnumType.STRING) protected CommonHealthStatus healthStatus = CommonHealthStatus.NOT_COLLECTED; @Column - + protected String healthStatusDescription; @Column protected Date deleted; @@ -115,6 +116,11 @@ public abstract class BaseDataSource implements IDataSource, Serializable, HasAr @Column(name = "dbms_type") private DBMSType dbmsType; + @SolrFieldAnno(filter = true) + @Column(name = "access_type") + @Enumerated(value = EnumType.STRING) + protected CommonDataSourceAccessType accessType; + @Override public SolrCollection getCollection() { @@ -301,4 +307,14 @@ public void setDbmsType(DBMSType dbmsType) { this.dbmsType = dbmsType; } + + public CommonDataSourceAccessType getAccessType() { + + return accessType; + } + + public void setAccessType(CommonDataSourceAccessType accessType) { + + this.accessType = accessType; + } } diff --git a/src/main/java/com/odysseusinc/arachne/portal/model/IDataSource.java b/src/main/java/com/odysseusinc/arachne/portal/model/IDataSource.java index 97ed9baf6..630ece8c7 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/model/IDataSource.java +++ b/src/main/java/com/odysseusinc/arachne/portal/model/IDataSource.java @@ -22,6 +22,7 @@ package com.odysseusinc.arachne.portal.model; +import com.odysseusinc.arachne.commons.api.v1.dto.CommonDataSourceAccessType; import com.odysseusinc.arachne.commons.api.v1.dto.CommonHealthStatus; import com.odysseusinc.arachne.commons.api.v1.dto.CommonModelType; import com.odysseusinc.arachne.commons.types.CommonCDMVersionDTO; @@ -94,4 +95,8 @@ public interface IDataSource extends Breadcrumb, SolrEntity { DBMSType getDbmsType(); void setDbmsType(DBMSType dbmsType); + + CommonDataSourceAccessType getAccessType(); + + void setAccessType(CommonDataSourceAccessType accessType); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/BaseAnalysisRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/BaseAnalysisRepository.java index 263f1860b..4b5b61ec0 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/BaseAnalysisRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/BaseAnalysisRepository.java @@ -48,10 +48,6 @@ public interface BaseAnalysisRepository extends EntityGraphJ void deleteByIdIn(List ids); - T findById(Long id, EntityGraph entityGraph); - - T findById(Long id); - List findByIdIn(List ids); List findByStudyIdOrderByOrd(Long studyId, EntityGraph entityGraph); diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/BaseDataSourceRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/BaseDataSourceRepository.java index 74fb23a97..9de97ff36 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/BaseDataSourceRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/BaseDataSourceRepository.java @@ -46,8 +46,6 @@ public interface BaseDataSourceRepository extends EntityG " AND ds.deleted IS NULL\n" + " AND dn.is_virtual = FALSE\n"; - T findOne(Long id); - List findByIdInAndDeletedIsNullAndPublishedTrue(List ids); Optional findByName(String name); diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/BaseUserRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/BaseUserRepository.java index 8d5fa473b..5caaed122 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/BaseUserRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/BaseUserRepository.java @@ -78,8 +78,6 @@ List suggestToPaper(@Param("suggestRequest") String suggestRequest, @Param("paperId") Long paperId, @Param("limit") Integer limit); - U findById(Long id); - @Query(nativeQuery = true, value = "SELECT * FROM users_data u WHERE enabled = TRUE") List findAllEnabledFromAllTenants(); diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/PaperRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/PaperRepository.java index 26a59bf6b..2a8a4f641 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/PaperRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/PaperRepository.java @@ -30,8 +30,6 @@ public interface PaperRepository extends JpaRepository, JpaSpecificationExecutor { - int deleteById(Long id); - Optional findByStudyId(Long studyId); List findByStudyIdIn(List studyIds); diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/ResultFileRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/ResultFileRepository.java index 028eb6c74..96d1a4de0 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/ResultFileRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/ResultFileRepository.java @@ -29,8 +29,6 @@ public interface ResultFileRepository extends CrudRepository { - ResultFile findById(Long fileId); - ResultFile findByPath(String path); ResultFile findByCommentTopic(CommentTopic topic); diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/StudyDataSourceLinkRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/StudyDataSourceLinkRepository.java index a198acbe4..d2d1fddc0 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/StudyDataSourceLinkRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/StudyDataSourceLinkRepository.java @@ -54,8 +54,6 @@ StudyDataSourceLink findByDataSourceIdAndStudyId(@Param("dataSourceId") Long dat @Query(nativeQuery = true, value = "SELECT * FROM studies_data_sources WHERE study_id =:studyId") List findByStudyIdIncludingDeleted(@Param("studyId") Long studyId); - StudyDataSourceLink findById(Long id); - @Query(nativeQuery = true, value = "SELECT * FROM studies_data_sources WHERE id = :id") StudyDataSourceLink findByIdIncludingDeleted(@Param("id") Long id); diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/SubmissionResultFileRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/SubmissionResultFileRepository.java index 8365f98fc..ec34edeb8 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/SubmissionResultFileRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/SubmissionResultFileRepository.java @@ -33,7 +33,5 @@ public interface SubmissionResultFileRepository extends CrudRepository { - ResultFile findById(Long id); - ResultFile findByPath(String path); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/UserSpecifications.java b/src/main/java/com/odysseusinc/arachne/portal/repository/UserSpecifications.java index 4b6b29152..1ff0528ae 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/UserSpecifications.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/UserSpecifications.java @@ -29,7 +29,6 @@ import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.domain.Specifications; public class UserSpecifications { @@ -75,7 +74,7 @@ public static Specification usersIn(final Set tenantI public static Specification withNameLike(String namePattern) { - Specifications spec = Specifications.where(withFieldLike("firstname", namePattern)); + Specification spec = Specification.where(withFieldLike("firstname", namePattern)); return spec.or(withFieldLike("middlename", namePattern)) .or(withFieldLike("lastname", namePattern)); } @@ -87,7 +86,7 @@ public static Specification withEmailLike(String emailPatte public static Specification withNameOrEmailLike(String pattern) { - Specifications spec = Specifications.where(withNameLike(pattern)); + Specification spec = Specification.where(withNameLike(pattern)); return spec.or(withEmailLike(pattern)); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/UserStudyGroupedRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/UserStudyGroupedRepository.java index 3468d99ab..855f8672a 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/UserStudyGroupedRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/UserStudyGroupedRepository.java @@ -22,12 +22,9 @@ package com.odysseusinc.arachne.portal.repository; -import com.odysseusinc.arachne.portal.model.Study; import com.odysseusinc.arachne.portal.model.UserStudyGrouped; + import java.util.List; -import java.util.Optional; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.data.repository.CrudRepository; public interface UserStudyGroupedRepository extends BaseUserStudyLinkRepository { diff --git a/src/main/java/com/odysseusinc/arachne/portal/repository/submission/BaseSubmissionRepository.java b/src/main/java/com/odysseusinc/arachne/portal/repository/submission/BaseSubmissionRepository.java index 571f91bfe..9cc0fab1f 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/repository/submission/BaseSubmissionRepository.java +++ b/src/main/java/com/odysseusinc/arachne/portal/repository/submission/BaseSubmissionRepository.java @@ -73,10 +73,6 @@ T findByIdAndUpdatePasswordAndStatusIn(@Param("id") Long id, Optional findByIdAndToken(Long id, String token); - T findById(Long id); - - T findById(Long id, EntityGraph entityGraph); - @Query(nativeQuery = true, value = "SELECT n FROM ( " + " SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS n " + diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/ToPdfConverter.java b/src/main/java/com/odysseusinc/arachne/portal/service/ToPdfConverter.java index a78b68fc1..1431e6aa2 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/ToPdfConverter.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/ToPdfConverter.java @@ -30,10 +30,10 @@ import java.nio.file.Path; import com.odysseusinc.arachne.portal.exception.ArachneSystemRuntimeException; -import org.jodconverter.DocumentConverter; -import org.jodconverter.document.DefaultDocumentFormatRegistry; -import org.jodconverter.office.LocalOfficeManager; -import org.jodconverter.office.OfficeException; +import org.jodconverter.core.DocumentConverter; +import org.jodconverter.core.document.DefaultDocumentFormatRegistry; +import org.jodconverter.core.office.OfficeException; +import org.jodconverter.local.office.LocalOfficeManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/analysis/impl/BaseAnalysisServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/analysis/impl/BaseAnalysisServiceImpl.java index 535b010d3..9e20b0e28 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/analysis/impl/BaseAnalysisServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/analysis/impl/BaseAnalysisServiceImpl.java @@ -282,7 +282,7 @@ protected void moveStudyToActiveStatusIfAnalysisIsFirst(A saved) { public A update(A analysis) throws NotUniqueException, NotExistException, ValidationException { - A forUpdate = analysisRepository.findById(analysis.getId()); + A forUpdate = analysisRepository.getOne(analysis.getId()); if (forUpdate == null) { throw new NotExistException("update: analysis with id=" + analysis.getId() + " not exist", Analysis.class); } @@ -318,7 +318,7 @@ public A getById(Long id) throws NotExistException { "submissions.submissionGroup", "submissions.submissionInsight", "submissions.dataSource") - ); + ).orElseThrow(()-> new NotExistException(Analysis.class)); } @@ -337,7 +337,7 @@ private List list(Study study) { @Override public Boolean moveAnalysis(Long id, Integer index) { - A analysis = analysisRepository.findById(id); + A analysis = analysisRepository.getOne(id); Study study = analysis.getStudy(); List list = list(study); list.remove(analysis); @@ -389,7 +389,7 @@ public AnalysisFile getAnalysisFileUnsecured(String uuid) { @Override public void lockAnalysisFiles(Long analysisId, Boolean locked) throws NotExistException { - final Optional analysisOptional = Optional.of(analysisRepository.findById(analysisId)); + final Optional analysisOptional = analysisRepository.findById(analysisId); final A analysis = analysisOptional.orElseThrow(() -> { String message = String.format(ANALYSIS_NOT_FOUND_EXCEPTION, analysisId); return new NotExistException(message, Analysis.class); @@ -486,7 +486,7 @@ public Boolean forceDeleteAnalysisFile(A analysis, AnalysisFile analysisFile) { public void updateFile(String uuid, MultipartFile file, Long analysisId, Boolean isExecutable) throws IOException { - A analysis = analysisRepository.findById(analysisId); + A analysis = analysisRepository.getOne(analysisId); throwAccessDeniedExceptionIfLocked(analysis); try { AnalysisFile analysisFile = analysisFileRepository.findByUuid(uuid); @@ -682,7 +682,7 @@ protected void checkApproveSubmissionResultInitialState(SubmissionStatus initial @Override public void getAnalysisAllFiles(Long analysisId, String archiveName, OutputStream os) throws IOException { - Analysis analysis = analysisRepository.findById(analysisId); + Analysis analysis = analysisRepository.getOne(analysisId); Path storeFilesPath = analysisHelper.getAnalysisFolder(analysis); try (ZipOutputStream zos = new ZipOutputStream(os)) { for (AnalysisFile analysisFile : analysis.getFiles()) { @@ -712,13 +712,13 @@ public void fullDelete(List analyses) { for (A analysis : analyses) { List files = analysis.getFiles(); - analysisFileRepository.delete(files); + analysisFileRepository.deleteAll(files); for (AnalysisFile file : files) { deleteAnalysisFile(analysis, file); } } - analysisRepository.delete(analyses); + analysisRepository.deleteAll(analyses); } @Override @@ -733,7 +733,7 @@ public List getByStudyId(Long id, EntityGraph graph) { public void processAntivirusResponse(AntivirusJobAnalysisFileResponseEvent event) { final AntivirusJobResponse antivirusJobResponse = event.getAntivirusJobResponse(); - final AnalysisFile analysisFile = analysisFileRepository.findOne(antivirusJobResponse.getFileId()); + final AnalysisFile analysisFile = analysisFileRepository.getOne(antivirusJobResponse.getFileId()); if (analysisFile != null) { analysisFile.setAntivirusStatus(antivirusJobResponse.getStatus()); analysisFile.setAntivirusDescription(antivirusJobResponse.getDescription()); diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/domain/DomainObjectLoader.java b/src/main/java/com/odysseusinc/arachne/portal/service/domain/DomainObjectLoader.java index 62ce6b3e5..0786bdd45 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/domain/DomainObjectLoader.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/domain/DomainObjectLoader.java @@ -65,7 +65,7 @@ public DomainObjectLoader withTargetId(Object domainObject) { protected CrudRepository getRepository() { - return (CrudRepository) repositories.getRepositoryFor(domainClazz); + return (CrudRepository) repositories.getRepositoryFor(domainClazz).orElseThrow(() -> new IllegalArgumentException("Unknown class: " + domainClazz.getCanonicalName())); } protected Serializable getTargetId(Object domainObject) { diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/domain/GenericDomainObjectLoader.java b/src/main/java/com/odysseusinc/arachne/portal/service/domain/GenericDomainObjectLoader.java index f044f3f5e..ec111d904 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/domain/GenericDomainObjectLoader.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/domain/GenericDomainObjectLoader.java @@ -39,6 +39,6 @@ protected Serializable getTargetId(Object domainObject) { @Override public Object loadDomainObject() { - return targetId != null ? getRepository().findOne(targetId) : null; + return targetId != null ? getRepository().findById(targetId).orElse(null) : null; } } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseArachneSecureServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseArachneSecureServiceImpl.java index 08ea08dd2..f194088d0 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseArachneSecureServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseArachneSecureServiceImpl.java @@ -128,7 +128,7 @@ public List getRolesByStudy(ArachneUser user, Study study) { boolean requiredFieldsAreSet = ObjectUtils.allNotNull(study.getId(), study.getTenant(), study.getPrivacy()); if (!requiredFieldsAreSet) { - study = studyRepository.findOne(study.getId()); + study = studyRepository.getOne(study.getId()); } if (Objects.equals(study.getTenant().getId(), user.getActiveTenantId())) { @@ -153,7 +153,7 @@ public List getRolesByAnalysis(ArachneUser user, Analysis analy if (analysis.getStudy() != null) { result = getRolesByStudy(user, analysis.getStudy()); } else { - Analysis byId = analysisRepository.findOne(analysis.getId()); + Analysis byId = analysisRepository.getOne(analysis.getId()); result = byId != null ? getRolesByStudy(user, byId.getStudy()) : result; } if (Objects.nonNull(analysis.getAuthor()) && Objects.equals(analysis.getAuthor().getId(), user.getId())) { diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseAtlasServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseAtlasServiceImpl.java index 6c372afc7..49e1cd9ba 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseAtlasServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseAtlasServiceImpl.java @@ -46,18 +46,18 @@ public T register(T atlas) { @PostAuthorize("(returnObject != null && returnObject.dataNode == authentication.principal) || hasRole('ROLE_ADMIN')") public T findByIdInAnyTenant(Long id) { - return baseRawAtlasRepository.findOne(id); + return baseRawAtlasRepository.getOne(id); } @Override - @PreAuthorize("@dataNodeRepository.findOne(#dataNodeId) == authentication.principal || hasRole('ROLE_ADMIN')") + @PreAuthorize("@dataNodeRepository.getOne(#dataNodeId) == authentication.principal || hasRole('ROLE_ADMIN')") public T findByNameAndNodeInAnyTenant(String name, Long dataNodeId) { return baseRawAtlasRepository.findByNameAndDataNodeId(name, dataNodeId); } @Override - @PreAuthorize("@rawAtlasRepository.findOne(#id)?.dataNode == authentication.principal") + @PreAuthorize("@rawAtlasRepository.getOne(#id)?.dataNode == authentication.principal") public T update(Long id, T atlas) { T existing = findByIdInAnyTenant(id); @@ -81,10 +81,10 @@ public T updateUnsafeInAnyTenant(T atlas) { } @Override - @PreAuthorize("@rawAtlasRepository.findOne(#id)?.dataNode == authentication.principal") + @PreAuthorize("@rawAtlasRepository.getOne(#id)?.dataNode == authentication.principal") public void delete(Long id) { - baseRawAtlasRepository.delete(id); + baseRawAtlasRepository.deleteById(id); } } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataNodeServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataNodeServiceImpl.java index 43f56cf20..91af060bc 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataNodeServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataNodeServiceImpl.java @@ -178,7 +178,7 @@ public DN getBySid(String uuid) throws NotExistException { public DN getById(Long id) throws NotExistException { if (Objects.nonNull(id)) { - final DN dataNode = dataNodeRepository.findOne(id); + final DN dataNode = dataNodeRepository.getOne(id); if (dataNode == null) { final String message = String.format(IS_NOT_FOUND_EXCEPTION, id); throw new NotExistException(message, DataNode.class); @@ -192,7 +192,7 @@ public DN getById(Long id) throws NotExistException { public DN getByIdUnsecured(Long id) throws NotExistException { if (Objects.nonNull(id)) { - final DN dataNode = dataNodeRepository.findOne(id); + final DN dataNode = dataNodeRepository.getOne(id); if (dataNode == null) { final String message = String.format(IS_NOT_FOUND_EXCEPTION, id); throw new NotExistException(message, DataNode.class); diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataSourceServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataSourceServiceImpl.java index 29f66c43e..d80ae6652 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataSourceServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseDataSourceServiceImpl.java @@ -22,6 +22,7 @@ package com.odysseusinc.arachne.portal.service.impl; +import com.odysseusinc.arachne.commons.api.v1.dto.CommonDataSourceAccessType; import com.odysseusinc.arachne.commons.api.v1.dto.CommonModelType; import com.odysseusinc.arachne.portal.api.v1.dto.PageDTO; import com.odysseusinc.arachne.portal.api.v1.dto.SearchDataCatalogDTO; @@ -280,6 +281,10 @@ private DS baseUpdate(DS exist, DS dataSource) { exist.setCdmVersion(CommonModelType.CDM.equals(dataSource.getModelType()) ? dataSource.getCdmVersion() : null); } + if (dataSource.getAccessType() != null) { + exist.setAccessType(dataSource.getAccessType()); + } + if (dataSource.getPublished() != null) { exist.setPublished(dataSource.getPublished()); if (dataSource.getPublished()) { @@ -346,7 +351,7 @@ public DS getByIdUnsecured(Long id) { if (id == null) { throw new NotExistException("id is null", getType()); } - DS dataSource = rawDataSourceRepository.findOne(id); + DS dataSource = rawDataSourceRepository.findById(id).orElse(null); if (dataSource == null) { throw new NotExistException(getType()); } @@ -409,7 +414,7 @@ public Page suggestDataSource(final String query, final Long studyId, final cb.isFalse(root.get("dataNode").get("virtual")))); TypedQuery typedQuery = this.entityManager.createQuery(cq); - List list = typedQuery.setFirstResult(pageRequest.getOffset()) + List list = typedQuery.setFirstResult((int)pageRequest.getOffset()) .setMaxResults(pageRequest.getPageSize()) .getResultList(); return new PageImpl<>(list, pageRequest, list.size()); @@ -423,7 +428,7 @@ public void delete(Long id) { log.info("Deleting datasource with id={}", id); makeLinksWithTenantsDeleted(id); - rawDataSourceRepository.delete(id); + rawDataSourceRepository.deleteById(id); } @PreAuthorize("hasPermission(#id, 'RawDataSource', " @@ -491,9 +496,9 @@ public PageRequest getPageRequest(PageDTO pageDTO) throws PermissionDeniedExcept @Override public PageRequest getPageRequest(PageDTO pageDTO, String sortBy, String order) throws PermissionDeniedException { - List dsSortBy = DataSourceSortMapper.map(Arrays.asList(StringUtils.split(sortBy, ","))); - Sort sort = new Sort(Sort.Direction.fromString(order), dsSortBy); - return new PageRequest(pageDTO.getPage() - 1, pageDTO.getPageSize(), sort); + String[] dsSortBy = DataSourceSortMapper.map(Arrays.asList(StringUtils.split(sortBy, ","))).stream().toArray(String[]::new); + Sort sort = Sort.by(Sort.Direction.fromString(order), dsSortBy); + return PageRequest.of(pageDTO.getPage() - 1, pageDTO.getPageSize(), sort); } @Override diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BasePaperServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BasePaperServiceImpl.java index 3fdb18e2d..5444bfa81 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BasePaperServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BasePaperServiceImpl.java @@ -167,7 +167,7 @@ protected void beforePaperSave(P newPaper) { public Page

getPapersAccordingToCurrentUser(PS paperSearch, IUser user) { final PaperSpecification

paperSpecification = new PaperSpecification<>(paperSearch, user); - return paperRepository.findAll(paperSpecification, new PageRequest(paperSearch.getPage(), paperSearch.getPageSize())); + return paperRepository.findAll(paperSpecification, PageRequest.of(paperSearch.getPage(), paperSearch.getPageSize())); } @@ -179,7 +179,7 @@ public P get(Long id) { private P getPaperByIdOrThrow(Long id) { - return Optional.ofNullable(paperRepository.findOne(id)) + return Optional.ofNullable(paperRepository.getOne(id)) .orElseThrow(() -> new NotExistException(Paper.class)); } @@ -237,9 +237,7 @@ public void delete(Long id) throws FileNotFoundException { } } ); - if (paperRepository.deleteById(id) == 0) { - throw new NotExistException(Paper.class); - } + paperRepository.deleteById(id); } @PreAuthorize("hasPermission(#paperId, 'Paper', " @@ -329,13 +327,13 @@ public void deleteFile(Long paperId, String fileUuid, PaperFileType fileType) th case PAPER: { paperFile = paperPaperFileRepository.findByPaperIdAndUuid(paperId, fileUuid) .orElseThrow(() -> new NotExistException(AbstractPaperFile.class)); - paperPaperFileRepository.delete(paperFile.getId()); + paperPaperFileRepository.deleteById(paperFile.getId()); break; } case PROTOCOL: { paperFile = paperProtocolFileRepository.findByPaperIdAndUuid(paperId, fileUuid) .orElseThrow(() -> new NotExistException(AbstractPaperFile.class)); - paperProtocolFileRepository.delete(paperFile.getId()); + paperProtocolFileRepository.deleteById(paperFile.getId()); break; } default: { @@ -455,15 +453,15 @@ public void fullDelete(List

papers) { for (P paper : papers) { List paperPaperFiles = paper.getPapers(); - paperPaperFileRepository.delete(paperPaperFiles); + paperPaperFileRepository.deleteAll(paperPaperFiles); fileService.delete(paperPaperFiles); List protocolFiles = paper.getProtocols(); - paperProtocolFileRepository.delete(protocolFiles); + paperProtocolFileRepository.deleteAll(protocolFiles); fileService.delete(protocolFiles); } - paperRepository.delete(papers); + paperRepository.deleteAll(papers); } @Override @@ -505,7 +503,7 @@ public void processAntivirusResponse(AntivirusJobPaperProtocolFileResponseEvent private void update(AntivirusJobResponseEventBase event, JpaRepository repository) { final AntivirusJobResponse antivirusJobResponse = event.getAntivirusJobResponse(); - final AntivirusFile file = (AntivirusFile) repository.findOne(antivirusJobResponse.getFileId()); + final AntivirusFile file = (AntivirusFile) repository.getOne(antivirusJobResponse.getFileId()); if (file != null) { file.setAntivirusStatus(antivirusJobResponse.getStatus()); file.setAntivirusDescription(antivirusJobResponse.getDescription()); diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseRoleServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseRoleServiceImpl.java index 37cc5773d..60e849a62 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseRoleServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseRoleServiceImpl.java @@ -52,7 +52,7 @@ public R create(R role) throws NotUniqueException { @Override public R update(R role) throws NotUniqueException, NotExistException { - if (!roleRepository.exists(role.getId())) { + if (!roleRepository.existsById(role.getId())) { throw new NotExistException("update: role with id=" + role.getId() + " not exist", getType()); } List roles = roleRepository.findByName(role.getName()); diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseSkillServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseSkillServiceImpl.java index 302689890..0cde14eba 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseSkillServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseSkillServiceImpl.java @@ -61,7 +61,7 @@ public S create(S skill) throws NotUniqueException { @Override public S update(S skill) throws NotUniqueException, NotExistException { - if (!skillRepository.exists(skill.getId())) { + if (!skillRepository.existsById(skill.getId())) { throw new NotExistException("update: skill with id=" + skill.getId() + " not exist", getType()); } List skills = skillRepository.findByName(skill.getName()); diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseStudyServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseStudyServiceImpl.java index 4217effdb..666533009 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseStudyServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseStudyServiceImpl.java @@ -192,7 +192,7 @@ public abstract class BaseStudyServiceImpl< private final Map studySortPaths = new HashMap<>(); protected final ApplicationEventPublisher eventPublisher; private final BaseSolrService solrService; - + public BaseStudyService proxy; public BaseStudyServiceImpl(final UserStudyExtendedRepository userStudyExtendedRepository, @@ -259,6 +259,7 @@ private void init() { this.studySortPaths.put("leadList", new String[]{"firstLead.firstname", "firstLead.middlename", "firstLead.lastname"}); this.studySortPaths.put("role", new String[]{"role"}); this.studySortPaths.put("created", new String[]{"study.created"}); + this.studySortPaths.put("updated", new String[]{"study.updated"}); this.studySortPaths.put("type", new String[]{"study.type.name"}); this.studySortPaths.put("status", new String[]{"study.status"}); @@ -330,10 +331,10 @@ public void delete(Long studyId) throws NotExistException { if (studyId == null) { throw new NotExistException("id is null", getType()); } - if (!studyRepository.exists(studyId)) { + if (!studyRepository.existsById(studyId)) { throw new NotExistException(getType()); } - studyRepository.delete(studyId); + studyRepository.deleteById(studyId); } @Override @@ -368,7 +369,7 @@ public T update(T study) if (!byTitle.isEmpty()) { throw new NotUniqueException("title", "not unique"); } - T forUpdate = studyRepository.findOne(study.getId()); + T forUpdate = studyRepository.getOne(study.getId()); if (forUpdate == null) { throw new NotExistException(getType()); } @@ -401,7 +402,7 @@ public T update(T study) @Override public void setFavourite(Long userId, Long studyId, Boolean isFavourite) throws NotExistException { - Study study = studyRepository.findOne(studyId); + Study study = studyRepository.getOne(studyId); if (study == null) { throw new NotExistException("study not exist", Study.class); } @@ -421,7 +422,7 @@ public Page findStudies(final SS studySearch) { Page resultPage = baseUserStudyLinkRepository.findAll( studyFilteredListSpecification, - new PageRequest(studySearch.getPage() - 1, studySearch.getPagesize(), sort)); + PageRequest.of(studySearch.getPage() - 1, studySearch.getPagesize(), sort)); return resultPage.map(s -> (AbstractUserStudyListItem) s); } @@ -450,12 +451,12 @@ public SU getStudy(final IUser user, final Long studyId) { userStudyItem.getStudy().setDataSources(dataSourceLinks); return userStudyItem; } - + @Override public StudyKind getEntityStudyKind(final EntityType type, final Long id) { - + final Optional kind; - + switch (type) { case ANALYSIS: kind = studyRepository.findStudyKindByAnalysisId(id); @@ -478,7 +479,7 @@ public StudyKind getEntityStudyKind(final EntityType type, final Long id) { default: throw new IllegalArgumentException("Can't get study kind of entity with type = " + type); } - + return kind.orElseThrow(() -> new IllegalArgumentException(String.format("Study doesn't exist for %s entity with id %d", type, id))); } @@ -500,7 +501,7 @@ protected final Sort getSort(String sortBy, Boolean sortAsc) { Arrays.asList(studySortPaths.getOrDefault(sortBy, new String[]{defaultSort})).forEach((param) -> orders.add(new Sort.Order(sortDirection, param).ignoreCase())); - return new Sort(orders); + return Sort.by(orders); } @@ -515,7 +516,7 @@ public UserStudy addParticipant( String message ) throws NotExistException, AlreadyExistException { - Study study = Optional.ofNullable(studyRepository.findOne(studyId)) + Study study = Optional.ofNullable(studyRepository.getOne(studyId)) .orElseThrow(() -> new NotExistException(EX_STUDY_NOT_EXISTS, Study.class)); IUser participant = Optional.ofNullable(userService.findOne(participantId)) @@ -557,7 +558,7 @@ public UserStudy updateParticipantRole(Long studyId, Long participantId, ParticipantRole role) throws NotExistException, AlreadyExistException, ValidationException { - Study study = Optional.ofNullable(studyRepository.findOne(studyId)) + Study study = Optional.ofNullable(studyRepository.getOne(studyId)) .orElseThrow(() -> new NotExistException(EX_STUDY_NOT_EXISTS, Study.class)); IUser participant = Optional.ofNullable(userService.findOne(participantId)) .orElseThrow(() -> new NotExistException(EX_USER_NOT_EXISTS, User.class)); @@ -606,7 +607,7 @@ private void checkLastLeadInvestigator(UserStudy studyLink, Study study) throws public String saveFile(MultipartFile multipartFile, Long studyId, String label, IUser user) throws IOException { - Study study = studyRepository.findOne(studyId); + Study study = studyRepository.getOne(studyId); String fileNameLowerCase = UUID.randomUUID().toString(); try { @@ -646,7 +647,7 @@ public String saveFile(MultipartFile multipartFile, Long studyId, String label, + "T(com.odysseusinc.arachne.portal.security.ArachnePermission).UPLOAD_FILES)") public String saveFile(String link, Long studyId, String label, IUser user) throws IOException { - Study study = studyRepository.findOne(studyId); + Study study = studyRepository.getOne(studyId); String fileNameLowerCase = UUID.randomUUID().toString(); try { @@ -732,7 +733,7 @@ public List listApprovedDataSources(Long studyId) { public StudyDataSourceLink addDataSource(IUser createdBy, Long studyId, Long dataSourceId) throws NotExistException, AlreadyExistException { - T study = studyRepository.findOne(studyId); + T study = studyRepository.getOne(studyId); if (study == null) { throw new NotExistException("study not exist", Study.class); } @@ -773,7 +774,7 @@ public DS addVirtualDataSource( throws NotExistException, AlreadyExistException, NoSuchFieldException, IOException, ValidationException, FieldException, IllegalAccessException, SolrServerException { - Study study = studyRepository.findOne(studyId); + Study study = studyRepository.getOne(studyId); List dataNodeOwners = validateVirtualDataSourceOwners(study, dataOwnerIds); @@ -837,7 +838,7 @@ public DS getStudyDataSource(IUser user, Long studyId, Long dataSourceId) { + "T(com.odysseusinc.arachne.portal.security.ArachnePermission).DELETE_DATASOURCE)") public DS updateVirtualDataSource(IUser user, Long studyId, Long dataSourceId, String name, List dataOwnerIds) throws IllegalAccessException, IOException, NoSuchFieldException, SolrServerException, ValidationException { - Study study = studyRepository.findOne(studyId); + Study study = studyRepository.getOne(studyId); List dataOwners = validateVirtualDataSourceOwners(study, dataOwnerIds); @@ -873,7 +874,7 @@ public void removeDataSourceUnsecured(Long studyId, Long dataSourceId) { if (studyDataSourceLink == null) { throw new NotExistException("studyDataSourceLink does not exist.", StudyDataSourceLink.class); } - studyDataSourceLinkRepository.delete(studyDataSourceLink.getId()); + studyDataSourceLinkRepository.deleteById(studyDataSourceLink.getId()); } @Override @@ -926,15 +927,11 @@ public boolean fullDelete(List studies) { List files = study.getFiles(); fileService.delete(files); - studyFileRepository.delete(files); - - studyDataSourceLinkRepository.delete(study.getDataSources()); - + studyFileRepository.deleteAll(files); + studyDataSourceLinkRepository.deleteAll(study.getDataSources()); studyHelper.tryDeleteStudyFolder(study); } - - studyRepository.delete(studies); - + studyRepository.deleteAll(studies); return Boolean.TRUE; } @@ -984,7 +981,7 @@ public Iterable suggestStudy(String query, IUser owner, Long id, SuggestSearc + "T(com.odysseusinc.arachne.portal.security.ArachnePermission).ACCESS_STUDY)") public void getAllStudyFilesExceptLinks(Long studyId, String archiveName, OutputStream os) throws IOException { - T study = studyRepository.findOne(studyId); + T study = studyRepository.getOne(studyId); Path storeFilesPath = fileService.getPath(study); List files = study.getFiles() @@ -1017,7 +1014,7 @@ private Set updateDataNodeOwners(List dataOwners, DataNode public void processAntivirusResponse(AntivirusJobStudyFileResponseEvent event) { final AntivirusJobResponse antivirusJobResponse = event.getAntivirusJobResponse(); - final StudyFile studyFile = studyFileRepository.findOne(antivirusJobResponse.getFileId()); + final StudyFile studyFile = studyFileRepository.getOne(antivirusJobResponse.getFileId()); if (studyFile != null) { studyFile.setAntivirusStatus(antivirusJobResponse.getStatus()); studyFile.setAntivirusDescription(antivirusJobResponse.getDescription()); @@ -1061,7 +1058,7 @@ public T findByIdInAnyTenant(final Long studyId) { public T findWorkspaceForUser(IUser user, Long userId) throws NotExistException { final T workspace = studyRepository.findWorkspaceForUser(userId); - + if (workspace == null) { throw new NotExistException(getType()); } @@ -1083,13 +1080,13 @@ public T findOrCreateWorkspaceForUser(IUser user, Long userId) { } protected BaseStudyService getProxy() { - + return this.proxy; } - + @Override public void setProxy(final Object proxy) { - + this.proxy = (BaseStudyService)proxy; } } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseUserServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseUserServiceImpl.java index 502f39d1a..da5c4169b 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseUserServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BaseUserServiceImpl.java @@ -107,7 +107,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specifications; +import org.springframework.data.jpa.domain.Specification; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.prepost.PreAuthorize; @@ -147,7 +147,7 @@ import static com.odysseusinc.arachne.portal.service.RoleService.ROLE_ADMIN; import static java.lang.Boolean.TRUE; import static org.apache.commons.collections.CollectionUtils.isEmpty; -import static org.springframework.data.jpa.domain.Specifications.where; +import static org.springframework.data.jpa.domain.Specification.where; public abstract class BaseUserServiceImpl< @@ -328,12 +328,10 @@ public void remove(Long id) throws ValidationException, UserNotFoundException, N if (id == null) { throw new ValidationException("remove user: id must be not null"); } - U user = rawUserRepository.findOne(id); - if (user == null) { - throw new UserNotFoundException("removeUser", "remove user: user not found"); - } + U user = rawUserRepository.findById(id).orElseThrow(()-> new UserNotFoundException("removeUser", "remove user: user not found")); + solrService.delete(user); - rawUserRepository.delete(user.getId()); + rawUserRepository.deleteById(user.getId()); } @Override @@ -480,20 +478,20 @@ public void resendActivationEmail(final U user) { @Override public U getByIdInAnyTenantAndInitializeCollections(Long id) { - return initUserCollections(rawUserRepository.findOne(id)); + return initUserCollections(rawUserRepository.getOne(id)); } @Override public U getByUuidInAnyTenantAndInitializeCollections(String uuid) { final Long id = UserIdUtils.uuidToId(uuid); - return initUserCollections(rawUserRepository.findOne(id)); + return initUserCollections(rawUserRepository.findById(id).orElse(null)); } @Override public U getById(Long id) { - return userRepository.findOne(id); + return userRepository.getOne(id); } private void afterUpdate(U savedUser) { @@ -548,12 +546,12 @@ private U baseUpdate(U forUpdate, U user) { forUpdate.setZipCode(user.getZipCode()); } if (user.getCountry() != null) { - Country country = user.getCountry().getId() != null ? countryRepository.findOne(user.getCountry().getId()) : null; + Country country = user.getCountry().getId() != null ? countryRepository.findById(user.getCountry().getId()).orElse(null) : null; forUpdate.setCountry(country); } if (user.getStateProvince() != null) { Long stateProvinceId = user.getStateProvince().getId(); - StateProvince stateProvince = stateProvinceId != null ? stateProvinceRepository.findOne(stateProvinceId) : null; + StateProvince stateProvince = stateProvinceId != null ? stateProvinceRepository.findById(stateProvinceId).orElse(null) : null; forUpdate.setStateProvince(stateProvince); } if (user.getAffiliation() != null) { @@ -576,7 +574,7 @@ private U baseUpdate(U forUpdate, U user) { public U update(final U user) throws IllegalAccessException, SolrServerException, IOException, NotExistException, NoSuchFieldException { - U forUpdate = rawUserRepository.findOne(user.getId()); + U forUpdate = rawUserRepository.findById(user.getId()).orElse(null); forUpdate = baseUpdate(forUpdate, user); U savedUser = rawUserRepository.saveAndFlush(forUpdate); savedUser = initUserCollections(savedUser); @@ -585,7 +583,7 @@ public U update(final U user) } @Override - @PreAuthorize("T(String).CASE_INSENSITIVE_ORDER.compare(@rawUserRepository.findOne(#user.id)?.getUsername(), authentication.principal.username)==0 || hasRole('ROLE_ADMIN')") + @PreAuthorize("T(String).CASE_INSENSITIVE_ORDER.compare(@rawUserRepository.getOne(#user.id)?.getUsername(), authentication.principal.username)==0 || hasRole('ROLE_ADMIN')") public U updateInAnyTenant(U user) throws NotExistException { U forUpdate = getByIdInAnyTenant(user.getId()); forUpdate = baseUpdate(forUpdate, user); @@ -619,7 +617,7 @@ public void saveUsers(List users, Set tenants, boolean emailConfirmat public U getByUuid(String uuid) { if (uuid != null && !uuid.isEmpty()) { - return userRepository.findById(UserIdUtils.uuidToId(uuid)); + return userRepository.getOne(UserIdUtils.uuidToId(uuid)); } else { throw new IllegalArgumentException("Given uuid is blank"); } @@ -685,9 +683,9 @@ public List getAllEnabledFromAllTenants() { @Override public Page getPage(final Pageable pageable, final UserSearch userSearch) { - final Pageable pageableWithUpdatedOrder = new PageRequest(pageable.getPageNumber() - 1, pageable.getPageSize(), pageable.getSort()); + final Pageable pageableWithUpdatedOrder = PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize(), pageable.getSort()); - final Specifications spec = buildSpecification(userSearch); + final Specification spec = buildSpecification(userSearch); final Page page = rawUserRepository.findAll(spec, pageableWithUpdatedOrder); @@ -697,7 +695,7 @@ public Page getPage(final Pageable pageable, final UserSearch userSearch) { @Override public List getList(final UserSearch userSearch) { - final Specifications spec = buildSpecification(userSearch); + final Specification spec = buildSpecification(userSearch); return rawUserRepository.findAll(spec); } @@ -707,9 +705,9 @@ public List findUsersInAnyTenantByEmailIgnoreCaseIn(List emails) { return rawUserRepository.findByEmailIgnoreCaseIn(emails); } - private Specifications buildSpecification(final UserSearch userSearch) { + private Specification buildSpecification(final UserSearch userSearch) { - Specifications spec = where(UserSpecifications.hasEmail()); + Specification spec = where(UserSpecifications.hasEmail()); if (userSearch.getEmailConfirmed() != null) { spec = spec.and(emailConfirmed(userSearch.getEmailConfirmed())); } @@ -773,7 +771,7 @@ public void resetPassword(U user) NoSuchFieldException, SolrServerException, IOException { final Long id = user.getId(); - final U existingUser = rawUserRepository.findOne(id); + final U existingUser = rawUserRepository.findById(id).orElse(null); if (existingUser == null) { final String message = String.format("User with id='%s' does not exist", id); throw new NotExistException(message, User.class); @@ -791,7 +789,7 @@ public void resetPassword(U user) public void updatePassword(U user, String oldPassword, String newPassword) throws ValidationException, PasswordValidationException { - U exists = userRepository.findOne(user.getId()); + U exists = userRepository.getOne(user.getId()); if (!passwordEncoder.matches(oldPassword, user.getPassword())) { throw new ValidationException(PASSWORD_NOT_MATCH_EXC); @@ -805,7 +803,7 @@ public void updatePassword(U user, String oldPassword, String newPassword) public U addSkillToUser(Long userId, Long skillId) throws NotExistException, IllegalAccessException, SolrServerException, IOException, NoSuchFieldException { - U forUpdate = userRepository.findOne(userId); + U forUpdate = userRepository.getOne(userId); S skill = skillService.getById(skillId); forUpdate.getSkills().add(skill); U savedUser = initUserCollections(rawUserRepository.save(forUpdate)); @@ -818,7 +816,7 @@ public U addSkillToUser(Long userId, Long skillId) public U removeSkillFromUser(Long userId, Long skillId) throws NotExistException, IllegalAccessException, SolrServerException, IOException, NoSuchFieldException { - U forUpdate = userRepository.findOne(userId); + U forUpdate = userRepository.getOne(userId); Skill skill = skillService.getById(skillId); forUpdate.getSkills().remove(skill); U savedUser = initUserCollections(rawUserRepository.save(forUpdate)); @@ -831,7 +829,7 @@ public U removeSkillFromUser(Long userId, Long skillId) public U addLinkToUser(Long userId, UserLink link) throws NotExistException, NotUniqueException, PermissionDeniedException { - U forUpdate = userRepository.findOne(userId); + U forUpdate = userRepository.getOne(userId); link.setUser(forUpdate); userLinkService.create(link); return initUserCollections(forUpdate); @@ -851,7 +849,7 @@ private U initUserCollections(U user) { public U removeLinkFromUser(Long userId, Long linkId) throws NotExistException { userLinkService.delete(linkId); - U user = userRepository.findOne(userId); + U user = userRepository.getOne(userId); user.getLinks().size(); return initUserCollections(user); } @@ -860,7 +858,7 @@ public U removeLinkFromUser(Long userId, Long linkId) throws NotExistException { public U addPublicationToUser(Long userId, UserPublication publication) throws NotExistException, NotUniqueException, PermissionDeniedException { - U forUpdate = userRepository.findOne(userId); + U forUpdate = userRepository.getOne(userId); publication.setUser(forUpdate); UserPublication userPublication = userPublicationService.create(publication); forUpdate.getPublications().add(userPublication); @@ -871,7 +869,7 @@ public U addPublicationToUser(Long userId, UserPublication publication) public U removePublicationFromUser(Long userId, Long publicationId) throws NotExistException { userPublicationService.delete(publicationId); - U user = userRepository.findOne(userId); + U user = userRepository.getOne(userId); user.getPublications().size(); return (U) initUserCollections(user); } @@ -1136,9 +1134,9 @@ public List getAllAdmins(final String sortBy, final Boolean sortAsc) { Sort.Direction direction = sortAsc != null && sortAsc ? Sort.Direction.ASC : Sort.Direction.DESC; final Sort sort; if (sortBy == null || sortBy.isEmpty() || sortBy.equals("name")) { - sort = new Sort(direction, "firstname", "lastname", "middlename"); + sort = Sort.by(direction, "firstname", "lastname", "middlename"); } else { - sort = new Sort(direction, sortBy); + sort = Sort.by(direction, sortBy); } List admins = rawUserRepository.findByRoles_name(ROLE_ADMIN, sort); return admins; @@ -1147,7 +1145,7 @@ public List getAllAdmins(final String sortBy, final Boolean sortAsc) { @Override public void addUserToAdmins(Long id) { - U user = rawUserRepository.findOne(id); + U user = rawUserRepository.getOne(id); List roles = roleRepository.findByName(ROLE_ADMIN); if (roles != null && !roles.isEmpty()) { user.getRoles().add(roles.get(0)); @@ -1160,7 +1158,7 @@ public void addUserToAdmins(Long id) { @Override public void removeUserFromAdmins(Long id) { - U user = rawUserRepository.findOne(id); + U user = rawUserRepository.getOne(id); List roles = roleRepository.findByName(ROLE_ADMIN); if (roles != null && !roles.isEmpty()) { user.getRoles().remove(roles.get(0)); @@ -1185,7 +1183,7 @@ public List getUnlockAnalysisRequests(U user) { @Override public U findOne(Long participantId) { - return userRepository.findOne(participantId); + return userRepository.getOne(participantId); } @Override @@ -1256,7 +1254,7 @@ public void makeLinksWithStudiesDeleted(final Long tenantId, final Long userId) @Override public U getRawUser(final Long userId) { - return rawUserRepository.findOne(userId); + return rawUserRepository.getOne(userId); } @Override diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BreadcrumbServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BreadcrumbServiceImpl.java index 1b330295b..66edf739b 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/BreadcrumbServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/BreadcrumbServiceImpl.java @@ -84,7 +84,7 @@ private Breadcrumb getBreadcrumbByTypeAndId(EntityType type, Long id) throws Not case ANALYSIS: return analysisRepository.getOne(id); case SUBMISSION_GROUP: - return submissionGroupRepository.findOne(id); + return submissionGroupRepository.getOne(id); case SUBMISSION: return submissionRepository.getOne(id); case INSIGHT: @@ -94,7 +94,7 @@ private Breadcrumb getBreadcrumbByTypeAndId(EntityType type, Long id) throws Not case DATA_SOURCE: return dataSourceRepository.getOne(id); case PAPER: - return paperRepository.findOne(id); + return paperRepository.getOne(id); } return null; } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/CRUDLServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/CRUDLServiceImpl.java index efb72ec7e..2ef9c0a32 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/CRUDLServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/CRUDLServiceImpl.java @@ -43,10 +43,8 @@ public T getById(Long id) throws NotExistException { if (id == null) { throw new NotExistException("id is null", getType()); } - T entity = getRepository().findOne(id); - if (entity == null) { - throw new NotExistException(getType()); - } + T entity = getRepository().findById(id).orElseThrow(() -> new NotExistException(getType())); + return entity; } @@ -56,7 +54,7 @@ public void delete(Long id) throws NotExistException { if (id == null) { throw new NotExistException("id is null", getType()); } - getRepository().delete(id); + getRepository().deleteById(id); } @Override diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/CommentServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/CommentServiceImpl.java index 10f593461..a25b20d61 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/CommentServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/CommentServiceImpl.java @@ -80,7 +80,7 @@ public CommentTopic getTopic(Long id) throws NotExistException { @Override public Set list(Set topics, Integer size, Sort sort) { - Pageable pageable = new PageRequest(0, size, sort); + Pageable pageable = PageRequest.of(0, size, sort); final Page page = commentRepository.getAllByTopicIn(topics, pageable); final List comments = page.getContent(); comments.forEach(comment -> connectToTopic(topics, comment)); @@ -110,7 +110,7 @@ public Comment addComment(Long topicId, Long parentId, Comment comment) { final CommentTopic topic = commentTopicRepository.getOne(topicId); comment.setTopic(topic); if (parentId != null) { - final Comment parent = commentRepository.findOne(parentId); + final Comment parent = commentRepository.findById(parentId).orElse(null); comment.setParent(parent); } return commentRepository.save(comment); @@ -130,7 +130,7 @@ public void deleteComment(Long topicId, Long commentId) throws NotExistException @Override public void deleteComments(List comments) { - commentRepository.delete(comments); + commentRepository.deleteAll(comments); } @Override diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/DataNodeStatusServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/DataNodeStatusServiceImpl.java index 63454fb27..532e19933 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/DataNodeStatusServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/DataNodeStatusServiceImpl.java @@ -55,14 +55,14 @@ public DataNodeStatus createUpdate(DataNodeStatus studyStatus) { public Optional getById(Long id) { checkNotNull(id, "getByIdAndInitializeCollections: dataNodeStatus with id=null not exist"); - return Optional.ofNullable(dataNodeStatusRepository.findOne(id)); + return Optional.ofNullable(dataNodeStatusRepository.getOne(id)); } @Override public void delete(Long id) { checkNotNull(id, "deleteComment: cannot deleteComment DataNodeStatus with id=null"); - dataNodeStatusRepository.delete(id); + dataNodeStatusRepository.deleteById(id); } @Override diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/OrganizationServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/OrganizationServiceImpl.java index 2b5fb6c3f..97d30e3e9 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/OrganizationServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/OrganizationServiceImpl.java @@ -126,7 +126,7 @@ public Organization update(Organization organization) { public void delete(Long id) { final Organization exist = getById(id); - organizationRepository.delete(id); + organizationRepository.deleteById(id); logger.info("{} deleted", exist); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/ProfessionalTypeServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/ProfessionalTypeServiceImpl.java index d1995cbe4..a8b83ea37 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/ProfessionalTypeServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/ProfessionalTypeServiceImpl.java @@ -66,7 +66,7 @@ public CrudRepository getRepository() { @Override public ProfessionalType update(ProfessionalType professionalType) throws NotExistException, NotUniqueException { - if (!professionalTypeRepository.exists(professionalType.getId())) { + if (!professionalTypeRepository.existsById(professionalType.getId())) { throw new NotExistException("update: professionalType with id=" + professionalType.getId() + " not exist", ProfessionalType.class); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyStatusServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyStatusServiceImpl.java index a390b5668..d7c9bffa5 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyStatusServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyStatusServiceImpl.java @@ -61,7 +61,7 @@ public StudyStatus create(StudyStatus studyStatus) throws NotUniqueException { @Override public StudyStatus update(StudyStatus studyStatus) throws NotUniqueException, NotExistException { - if (!studyStatusRepository.exists(studyStatus.getId())) { + if (!studyStatusRepository.existsById(studyStatus.getId())) { throw new NotExistException("update: studyStatus with id=" + studyStatus.getId() + " not exist", StudyStatus.class); } StudyStatus existStudyStatus = studyStatusRepository.findByName(studyStatus.getName()); diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyTypeServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyTypeServiceImpl.java index eede774f1..5a7876750 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyTypeServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/StudyTypeServiceImpl.java @@ -61,7 +61,7 @@ public StudyType create(StudyType studyType) throws NotUniqueException { @Override public StudyType update(StudyType studyType) throws NotUniqueException, NotExistException { - if (!studyTypeRepository.exists(studyType.getId())) { + if (!studyTypeRepository.existsById(studyType.getId())) { throw new NotExistException("update: studyType with id=" + studyType.getId() + " not exist", StudyType.class); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/impl/UsersOperationsServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/impl/UsersOperationsServiceImpl.java index d16b8f18b..4798c998b 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/impl/UsersOperationsServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/impl/UsersOperationsServiceImpl.java @@ -81,6 +81,6 @@ private void toggleFlag( for (final IUser entity : entities) { setter.accept(entity, !getter.apply(entity)); } - baseRawUserRepository.save(entities); + baseRawUserRepository.saveAll(entities); } } \ No newline at end of file diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSender.java b/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSender.java index 373f5440f..37e4f94b0 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSender.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSender.java @@ -22,89 +22,14 @@ package com.odysseusinc.arachne.portal.service.mail; -import java.io.File; -import java.net.URL; -import java.util.Map; -import javax.mail.internet.MimeMessage; -import net.htmlparser.jericho.Source; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.mail.javamail.MimeMessageHelper; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import org.thymeleaf.TemplateEngine; -import org.thymeleaf.context.Context; - -@Service -public class ArachneMailSender { - private static final Logger LOG = LoggerFactory.getLogger(ArachneMailSender.class); - private static final String SIGNATURE = "signature"; - private static final String PATH_TO_TEMPLATES = "/templates/"; - private static final String NAME = "_text"; - private static final String EXTENSION = ".txt"; - - @Autowired - private TemplateEngine templateEngine; - - private JavaMailSender mailSender; - - @Value("${arachne.mail.notifier}") - private String from; - - @Value("${arachne.mail.signature}") - private String signature; - @Value("${arachne.mail.app-title}") - private String appTitle; - - @Autowired - public ArachneMailSender(JavaMailSender mailSender) { - - this.mailSender = mailSender; - } - - public void send(ArachneMailMessage mailMessage) { - - try { - MimeMessage message = mailSender.createMimeMessage(); - MimeMessageHelper helper; - helper = new MimeMessageHelper(message, true); - helper.setSubject(mailMessage.getSubject().replaceAll("\\$\\{app-title\\}", appTitle)); - helper.setFrom(from, mailMessage.getFromPersonal().replaceAll("\\$\\{app-title\\}", appTitle)); - helper.setTo(mailMessage.getUser().getEmail()); - URL templateUrl = this.getClass().getResource(PATH_TO_TEMPLATES + mailMessage.getTemplate() + NAME + EXTENSION); - String htmlString = buildContent(mailMessage.getTemplate(), mailMessage.getParameters()); - if (templateUrl != null) { - File textTemplate = new File(templateUrl.getPath()); - if (!textTemplate.isDirectory()) { - helper.setText(buildContent(mailMessage.getTemplate() + NAME, mailMessage.getParameters()), htmlString); - } - } else { - Source source = new Source(htmlString); - String textString = source.getRenderer().toString(); - helper.setText(textString, htmlString); - } - mailSender.send(message); - - } catch (Exception e) { - LOG.error(e.getMessage(), e); - } - } +import java.util.Map; - @Async - public void asyncSend(ArachneMailMessage mailMessage) { +public interface ArachneMailSender { - send(mailMessage); - } + void asyncSend(ArachneMailMessage mailMessage); - public String buildContent(String templateName, Map parameters) { + String buildContent(String templateName, Map parameters); - Context context = new Context(); - parameters.put(SIGNATURE, signature); - context.setVariables(parameters); - return templateEngine.process(templateName, context); - } + void send(ArachneMailMessage mailMessage); } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSenderImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSenderImpl.java new file mode 100644 index 000000000..a33cdfec2 --- /dev/null +++ b/src/main/java/com/odysseusinc/arachne/portal/service/mail/ArachneMailSenderImpl.java @@ -0,0 +1,114 @@ +/* + * + * Copyright 2021 Odysseus Data Services, inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Company: Odysseus Data Services, Inc. + * Product Owner/Architecture: Gregory Klebanov + * Authors: Alexandr Cumarav + * Created: April 20, 2021 + * + */ + +package com.odysseusinc.arachne.portal.service.mail; + +import net.htmlparser.jericho.Source; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.context.Context; + +import javax.mail.internet.MimeMessage; +import java.io.File; +import java.net.URL; +import java.util.Map; + +@Service +public class ArachneMailSenderImpl implements ArachneMailSender { + private static final Logger LOG = LoggerFactory.getLogger(ArachneMailSenderImpl.class); + private static final String SIGNATURE = "signature"; + private static final String PATH_TO_TEMPLATES = "/templates/"; + private static final String NAME = "_text"; + private static final String EXTENSION = ".txt"; + + @Autowired + private TemplateEngine templateEngine; + + private JavaMailSender mailSender; + + @Value("${arachne.mail.notifier}") + private String from; + + @Value("${arachne.mail.signature}") + private String signature; + + @Value("${arachne.mail.app-title}") + private String appTitle; + + @Autowired + public ArachneMailSenderImpl(JavaMailSender mailSender) { + + this.mailSender = mailSender; + } + + @Async + @Override + public void asyncSend(ArachneMailMessage mailMessage) { + + send(mailMessage); + } + + @Override + public String buildContent(String templateName, Map parameters) { + + Context context = new Context(); + parameters.put(SIGNATURE, signature); + context.setVariables(parameters); + return templateEngine.process(templateName, context); + } + + @Override + public void send(ArachneMailMessage mailMessage) { + + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper; + helper = new MimeMessageHelper(message, true); + helper.setSubject(mailMessage.getSubject().replaceAll("\\$\\{app-title\\}", appTitle)); + helper.setFrom(from, mailMessage.getFromPersonal().replaceAll("\\$\\{app-title\\}", appTitle)); + helper.setTo(mailMessage.getUser().getEmail()); + URL templateUrl = this.getClass().getResource(PATH_TO_TEMPLATES + mailMessage.getTemplate() + NAME + EXTENSION); + String htmlString = buildContent(mailMessage.getTemplate(), mailMessage.getParameters()); + if (templateUrl != null) { + File textTemplate = new File(templateUrl.getPath()); + if (!textTemplate.isDirectory()) { + helper.setText(buildContent(mailMessage.getTemplate() + NAME, mailMessage.getParameters()), htmlString); + } + } else { + Source source = new Source(htmlString); + String textString = source.getRenderer().toString(); + helper.setText(textString, htmlString); + } + mailSender.send(message); + + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddDataSourceStrategyFactoryImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddDataSourceStrategyFactoryImpl.java index 0a0693f9d..cbdc0db52 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddDataSourceStrategyFactoryImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddDataSourceStrategyFactoryImpl.java @@ -22,29 +22,44 @@ package com.odysseusinc.arachne.portal.service.study.impl; -import com.odysseusinc.arachne.portal.model.BaseDataSource; -import com.odysseusinc.arachne.portal.model.DataSource; +import com.odysseusinc.arachne.portal.model.IDataSource; import com.odysseusinc.arachne.portal.service.study.AddDataSourceStrategy; -import com.odysseusinc.arachne.portal.service.study.AddDataSourceStrategyFactory; -import java.util.Objects; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; +import java.util.Objects; + @Service -public class AddDataSourceStrategyFactoryImpl implements AddDataSourceStrategyFactory { +@Primary +public class AddDataSourceStrategyFactoryImpl extends BaseAddDataSourceStrategyFactory { - private final AddPublicDataSourceStrategy addPublicDataSourceStrategy; + private final AddPublicDataSourceStrategy publicDataSourceStrategy; + private final AddRestrictedDataSourceStrategy rectrictedDataSourceStrategy; @Autowired - public AddDataSourceStrategyFactoryImpl(AddPublicDataSourceStrategy addPublicDataSourceStrategy) { + public AddDataSourceStrategyFactoryImpl(AddPublicDataSourceStrategy addPublicDataSourceStrategy, + AddRestrictedDataSourceStrategy rectrictedDataSourceStrategy) { - this.addPublicDataSourceStrategy = addPublicDataSourceStrategy; + this.rectrictedDataSourceStrategy = rectrictedDataSourceStrategy; + publicDataSourceStrategy = addPublicDataSourceStrategy; } @Override - public AddDataSourceStrategy getStrategy(DataSource dataSource) { - - Objects.requireNonNull(dataSource); - return addPublicDataSourceStrategy; + public AddDataSourceStrategy getStrategy(IDataSource dataSource) { + // In case of virtual datasources we do not have access type + if (Objects.isNull(dataSource.getAccessType())) { + return publicDataSourceStrategy; + } + AddDataSourceStrategy strategy; + switch (dataSource.getAccessType()) { + case RESTRICTED: + strategy = rectrictedDataSourceStrategy; + break; + case PUBLIC: + default: + strategy = publicDataSourceStrategy; + } + return strategy; } } diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddRestrictedDataSourceStrategy.java b/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddRestrictedDataSourceStrategy.java new file mode 100644 index 000000000..3326f82ec --- /dev/null +++ b/src/main/java/com/odysseusinc/arachne/portal/service/study/impl/AddRestrictedDataSourceStrategy.java @@ -0,0 +1,77 @@ +/* + * + * Copyright 2018 Odysseus Data Services, inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Company: Odysseus Data Services, Inc. + * Product Owner/Architecture: Gregory Klebanov + * Authors: Pavel Grafkin, Alexandr Ryabokon, Vitaly Koulakov, Anton Gackovka, Maria Pozhidaeva, Mikhail Mironov + * Created: September 08, 2017 + * + */ +package com.odysseusinc.arachne.portal.service.study.impl; + +import com.odysseusinc.arachne.portal.api.v1.dto.UpdateNotificationDTO; +import com.odysseusinc.arachne.portal.config.WebSecurityConfig; +import com.odysseusinc.arachne.portal.model.DataNode; +import com.odysseusinc.arachne.portal.model.IDataSource; +import com.odysseusinc.arachne.portal.model.IUser; +import com.odysseusinc.arachne.portal.model.StudyDataSourceLink; +import com.odysseusinc.arachne.portal.repository.StudyDataSourceLinkRepository; +import com.odysseusinc.arachne.portal.service.mail.ArachneMailSender; +import com.odysseusinc.arachne.portal.service.mail.InvitationDataOwnerMailSender; +import com.odysseusinc.arachne.portal.service.study.AddDataSourceStrategy; +import com.odysseusinc.arachne.portal.util.DataNodeUtils; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Service; + +import static com.odysseusinc.arachne.portal.model.DataSourceStatus.APPROVED; +import static com.odysseusinc.arachne.portal.model.DataSourceStatus.PENDING; + +@Service +public class AddRestrictedDataSourceStrategy extends AbstractAddDataSourceStrategy implements AddDataSourceStrategy { + + private final ArachneMailSender arachneMailSender; + private final SimpMessagingTemplate wsTemplate; + + public AddRestrictedDataSourceStrategy(StudyDataSourceLinkRepository studyDataSourceLinkRepository, + ArachneMailSender arachneMailSender, + SimpMessagingTemplate wsTemplate) { + + super(studyDataSourceLinkRepository); + this.arachneMailSender = arachneMailSender; + this.wsTemplate = wsTemplate; + } + + @Override + public void addDataSourceToStudy(IUser createdBy, IDataSource dataSource, StudyDataSourceLink link) { + + DataNode dataNode = dataSource.getDataNode(); + if (DataNodeUtils.isDataNodeOwner(dataNode, createdBy)) { + saveStudyDataSourceLinkWithStatus(link, APPROVED); + } else { + StudyDataSourceLink studyDataSourceLink + = saveStudyDataSourceLinkWithStatus(link, PENDING); + DataNodeUtils.getDataNodeOwners(dataNode).forEach( + user -> { + arachneMailSender.send(new InvitationDataOwnerMailSender( + WebSecurityConfig.getDefaultPortalURI(), user, studyDataSourceLink + ) + ); + wsTemplate.convertAndSendToUser(user.getUsername(), "/topic/invitations", + new UpdateNotificationDTO()); + } + ); + } + } +} diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionInsightServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionInsightServiceImpl.java index 245696cab..db393a1e8 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionInsightServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionInsightServiceImpl.java @@ -109,17 +109,17 @@ public SubmissionInsight createSubmissionInsight(Long submissionId, SubmissionIn .stream() .map(sf -> new SubmissionInsightSubmissionFile(savedInsight, sf, new CommentTopic())) .collect(Collectors.toList()); - submissionInsightSubmissionFileRepository.save(submissionInsightSubmissionFiles); + submissionInsightSubmissionFileRepository.saveAll(submissionInsightSubmissionFiles); final List resultFiles = submission.getResultFiles(); resultFiles.forEach(resultFile -> resultFile.setCommentTopic(new CommentTopic())); - submissionResultFileRepository.save(resultFiles); + submissionResultFileRepository.saveAll(resultFiles); return savedInsight; } @Override public void deleteSubmissionInsightSubmissionFileLinks(List links) { - submissionInsightSubmissionFileRepository.delete(links); + submissionInsightSubmissionFileRepository.deleteAll(links); } @Override @@ -169,14 +169,14 @@ public void deleteSubmissionInsight(Long submissionId) throws NotExistException throwNotExistExceptionIfNull(submission.getSubmissionInsight(), submissionId); final List resultFiles = submission.getResultFiles(); resultFiles.forEach(resultFile -> resultFile.setCommentTopic(null)); - submissionResultFileRepository.save(resultFiles); + submissionResultFileRepository.saveAll(resultFiles); submissionInsightRepository.deleteBySubmissionId(submissionId); } @Override public void tryDeleteSubmissionInsight(Long submissionInsightId) { - submissionInsightRepository.delete(submissionInsightId); + submissionInsightRepository.deleteById(submissionInsightId); } private void throwNotExistExceptionIfNull(Submission submission, Long submissionId) throws NotExistException { diff --git a/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionServiceImpl.java b/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionServiceImpl.java index 86f125807..b904e82aa 100644 --- a/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionServiceImpl.java +++ b/src/main/java/com/odysseusinc/arachne/portal/service/submission/impl/BaseSubmissionServiceImpl.java @@ -88,6 +88,7 @@ import net.lingala.zip4j.model.FileHeader; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.tuple.Triple; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -119,11 +120,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Queue; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -205,7 +208,7 @@ protected BaseSubmissionServiceImpl(BaseSubmissionRepository submissionReposi @Override public T approveSubmissionResult(Long submissionId, ApproveDTO approveDTO, IUser user) { - T submission = submissionRepository.findOne(submissionId); + T submission = submissionRepository.getOne(submissionId); SubmissionStatus status = runApproveSubmissionProcess(submission, beforeApproveSubmissionResult(submission, approveDTO), approveDTO); List statusHistory = submission.getStatusHistory(); @@ -319,7 +322,7 @@ public T moveSubmissionToNewStatus(T submission, SubmissionStatus status, IUser @Override public T getSubmissionByIdUnsecured(Long id) throws NotExistException { - T submission = submissionRepository.findOne(id); + T submission = submissionRepository.getOne(id); throwNotExistExceptionIfNull(submission, id); return submission; } @@ -336,7 +339,7 @@ public T getSubmissionById(Long id) throws NotExistException { @Override public T getSubmissionById(Long id, EntityGraph entityGraph) throws NotExistException { - T submission = submissionRepository.findById(id, entityGraph); + T submission = submissionRepository.findById(id, entityGraph).orElse(null); throwNotExistExceptionIfNull(submission, id); return submission; } @@ -418,7 +421,7 @@ public SubmissionGroup createSubmissionGroup(IUser user, Analysis analysis) thro } files.add(submissionFile); } - submissionFileRepository.save(files); + submissionFileRepository.saveAll(files); submissionGroup.setChecksum(calculateMD5Hash(submissionGroupFolder, files)); submissionGroupRepository.save(submissionGroup); return submissionGroup; @@ -432,7 +435,7 @@ public Page getSubmissionGroups(SubmissionGroupSearch submissoi final SubmissionGroupSpecification submissionGroupSpecification = new SubmissionGroupSpecification(submissoinGroupSearch); final Integer page = submissoinGroupSearch.getPage(); - final PageRequest pageRequest = new PageRequest(page == null ? 0 : page - 1, submissoinGroupSearch.getPageSize(), new Sort(Sort.Direction.DESC, "created")); + final PageRequest pageRequest = PageRequest.of(page == null ? 0 : page - 1, submissoinGroupSearch.getPageSize(), Sort.by(Sort.Direction.DESC, "created")); final Page submissionGroups = submissionGroupRepository.findAll(submissionGroupSpecification, pageRequest); final List content = submissionGroups.getContent(); final Map submissionGroupMap = content.stream().collect(Collectors.toMap(SubmissionGroup::getId, sg -> { @@ -543,33 +546,64 @@ public T getSubmissionByIdAndToken(Long id, String token) throws NotExistExcepti @Override public void uploadCompressedResultsByDataOwner(Long submissionId, File compressedFile) throws IOException { - Submission submission = submissionRepository.findById(submissionId); + Submission submission = submissionRepository.getOne(submissionId); Objects.requireNonNull(submission); UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); IUser user = userService.getByUsername(userDetails.getUsername()); Path unzipDir = Files.createTempDirectory(String.format("submission_%d_results", submissionId)); - ZipFile zipFile = new ZipFile(compressedFile); - final List fileHeaders = zipFile.getFileHeaders().stream() - .filter(fileHeader -> !fileHeader.isDirectory()) - .collect(Collectors.toList()); try { - for (FileHeader fileHeader : fileHeaders) { - String relativeFilePath = fileHeader.getFileName(); - String relativePath = FilenameUtils.getPath(relativeFilePath); - if(isNotBlank(relativePath)){ - unzipDir.resolve(relativePath).toFile().mkdirs(); - } - final File localFile = unzipDir.resolve(relativeFilePath).toFile(); - FileUtils.copyInputStreamToFile(zipFile.getInputStream(fileHeader), localFile); - } + unzipWithNested(new ZipFile(compressedFile), unzipDir); storeExtractedFiles(submission, unzipDir, user.getId()); } finally { FileUtils.deleteDirectory(unzipDir.toFile()); } } + private void unzipWithNested(final ZipFile zipFile, final Path unzipDir) throws IOException { + final Queue> queue = zipFile.getFileHeaders().stream() + .filter(fh -> !fh.isDirectory()) + .map(fh -> Triple.of(unzipDir, zipFile, fh)) + .collect(Collectors.toCollection(LinkedList::new)); + + final Set filesToDelete = new HashSet<>(); + + while (!queue.isEmpty()) { + final Triple element = queue.poll(); + + final Path unzipPath = element.getLeft(); + final ZipFile zip = element.getMiddle(); + final FileHeader fileHeader = element.getRight(); + + final String relativeFilePath = fileHeader.getFileName(); + final String relativePath = FilenameUtils.getPath(relativeFilePath); + if (isNotBlank(relativePath)) { + unzipPath.resolve(relativePath).toFile().mkdirs(); + } + final File localFile = unzipPath.resolve(relativeFilePath).toFile(); + FileUtils.copyInputStreamToFile(zip.getInputStream(fileHeader), localFile); + + if (relativeFilePath.endsWith(".zip")) { + final ZipFile innerZipFile = new ZipFile(localFile); + if (innerZipFile.isValidZipFile()) { + final String relativePathWithoutExtension = FilenameUtils.removeExtension(relativeFilePath); + final Path zipFileNamedDir = unzipPath.resolve(relativePathWithoutExtension); + queue.addAll(innerZipFile.getFileHeaders().stream() + .filter(fh -> !fh.isDirectory()) + .map(fh -> Triple.of(zipFileNamedDir, innerZipFile, fh)) + .collect(Collectors.toCollection(LinkedList::new))); + filesToDelete.add(localFile); + } + } + } + + // delete unzipped zip files + for (final File file: filesToDelete) { + FileUtils.deleteQuietly(file); + } + } + @Override public ResultFile uploadResultFileByDataOwner(Long submissionId, File localFile) throws IOException { @@ -591,7 +625,7 @@ public ResultFile uploadResultFileByDataOwner(Long submissionId, File localFile) List resultFiles = submission.getResultFiles(); resultFiles.add(resultFile); submission.setUpdated(updated); - submissionResultFileRepository.save(resultFiles); + submissionResultFileRepository.saveAll(resultFiles); saveSubmission(submission); return resultFile; } @@ -608,13 +642,13 @@ private void storeExtractedFiles(Submission submission, Path unzipDir, long uplo resultFile.setPath(arachneFileMeta.getPath()); resultFiles.add(resultFile); } - submissionResultFileRepository.save(resultFiles); + submissionResultFileRepository.saveAll(resultFiles); } @Override public void getSubmissionAllFiles(Long submissionGroupId, String archiveName, OutputStream os) throws IOException { - SubmissionGroup submissionGroup = submissionGroupRepository.findOne(submissionGroupId); + SubmissionGroup submissionGroup = submissionGroupRepository.getOne(submissionGroupId); Path storeFilesPath = analysisHelper.getSubmissionGroupFolder(submissionGroup); try (ZipOutputStream zos = new ZipOutputStream(os)) { for (SubmissionFile submissionFile : submissionGroup.getFiles()) { @@ -663,19 +697,19 @@ public T approveSubmission(Long submissionId, Boolean isApproved, String comment @Override public SubmissionGroup getSubmissionGroupById(Long id) throws NotExistException { - return submissionGroupRepository.findOne(id); + return submissionGroupRepository.getOne(id); } @Override public void deleteSubmissionStatusHistory(List statusHistory) { - submissionStatusHistoryRepository.delete(statusHistory); + submissionStatusHistoryRepository.deleteAll(statusHistory); } @Override public SubmissionStatusHistoryElement getSubmissionStatusHistoryElementById(Long id) { - return submissionStatusHistoryRepository.findOne(id); + return submissionStatusHistoryRepository.findById(id).orElse(null); } @Override @@ -701,13 +735,13 @@ public T updateSubmission(T submission) { @Override public void deleteSubmissions(List submissions) { - submissionRepository.delete(submissions); + submissionRepository.deleteAll(submissions); } @Override public void deleteSubmissionGroups(List groups) { - submissionGroupRepository.delete(groups); + submissionGroupRepository.deleteAll(groups); } @Override @@ -769,7 +803,7 @@ public ResultFile createResultFile( @Override public List getResultFiles(IUser user, Long submissionId, ResultFileSearch resultFileSearch) throws PermissionDeniedException { - Submission submission = submissionRepository.findById(submissionId, EntityUtils.fromAttributePaths("dataSource", "dataSource.dataNode")); + Submission submission = submissionRepository.findById(submissionId, EntityUtils.fromAttributePaths("dataSource", "dataSource.dataNode")).get(); checkSubmissionPermission(user, submission); String resultFilesPath = contentStorageHelper.getResultFilesDir(submission, resultFileSearch.getPath()); @@ -806,7 +840,7 @@ public ResultFile getResultFileByPath(String path) { public ResultFile getResultFileById(Long fileId) { - return resultFileRepository.findById(fileId); + return resultFileRepository.findById(fileId).orElseThrow(IllegalArgumentException::new); } @Override @@ -818,7 +852,7 @@ public void getSubmissionResultAllFiles( OutputStream os) throws IOException, PermissionDeniedException { - Submission submission = submissionRepository.findOne(submissionId); + Submission submission = submissionRepository.getOne(submissionId); checkSubmissionPermission(user, submission); Path resultFilesPath = Paths.get(contentStorageHelper.getResultFilesDir(submission)); diff --git a/src/main/resources/application-base.yml b/src/main/resources/application-base.yml index a4d6b4635..8478e82df 100644 --- a/src/main/resources/application-base.yml +++ b/src/main/resources/application-base.yml @@ -17,25 +17,24 @@ logging: org.springframework.web.servlet.PageNotFound: ERROR spring: jpa: - database: POSTGRESQL + show-sql: true + database-platform: org.hibernate.dialect.PostgreSQL95Dialect properties: - hibernate: - jdbc: - batch_size: 20 - dialect: org.hibernate.dialect.PostgreSQLDialect - ddl-auto: none - connection: - CharSet: utf8 - characterEncoding: utf8 - useUnicode: true - show-sql: false + hibernate.jdbc.batch_size: 20 + hibernate.jdbc.lob.non_contextual_creation: true + hibernate.hbm2ddl.auto: none datasource: url: jdbc:postgresql://localhost:5434/arachne_portal username: ohdsi password: ENC(0Lpfvg9UPAyaaZpSIqwaDg==) driver-class-name: org.postgresql.Driver - max-active: 400 connection-test-query: select 1 + pool-name: Central-Pool + flyway: + out-of-order: true + table: "schema_version" + ignore-missing-migrations: true + enabled: true cache: jcache: config: classpath:ehcache.xml @@ -57,7 +56,7 @@ spring: throw-exception-if-no-handler-found: true thymeleaf: enabled: false - http: + servlet: multipart: max-file-size: 1024MB max-request-size: 1024MB @@ -67,20 +66,18 @@ spring: broker-url: vm://localhost?broker.persistent=true packages: trust-all: true + main: + allow-bean-definition-overriding: true +management: + endpoint: + restart: + enabled: true + health: + ldap: + enabled: false build: number: @build.number@ id: @build.id@ -flyway: - datasource: - driverClassName: org.postgresql.Driver - url: ${spring.datasource.url} - username: ${spring.datasource.username} - password: ${spring.datasource.password} - baseline-on-migrate: true - placeholderReplacement: false - out-of-order: true - validateOnMigrate: false - #locations: db/migration,classpath:com.odysseusinc.arachne.portal.db.migration arachne: token: secret: 129DF19C8A91AFD8375A2826A33539K01ACQ778QOJFAA9MGWLWH73PLXVFVHBR7860MTIE2O8EEVF9KCO77P6A7NUNX4XHAGCRFSBWG879XPDOIN6C2LFCKJI002OIABS4D6Q9VMJJIX8UCE48EF @@ -136,7 +133,8 @@ datanode: importTimeout: 60000 jasypt: encryptor: - password: + algorithm: PBEWITHMD5ANDDES + iv-generator-classname: org.jasypt.iv.NoIvGenerator achilles: executor: corePoolSize: 4 diff --git a/src/main/resources/db/migration/V20210622115059__datasource_access_type.sql b/src/main/resources/db/migration/V20210622115059__datasource_access_type.sql new file mode 100644 index 000000000..4ef57f38b --- /dev/null +++ b/src/main/resources/db/migration/V20210622115059__datasource_access_type.sql @@ -0,0 +1,18 @@ +ALTER TABLE data_sources_data + ADD COLUMN IF NOT EXISTS access_type VARCHAR NULL DEFAULT 'PUBLIC'; + +ALTER TABLE data_sources_data DROP CONSTRAINT data_sources_data_not_blank_fields_if_published; + +ALTER TABLE data_sources_data ADD CONSTRAINT data_sources_data_not_blank_fields_if_published + CHECK (published = FALSE OR (organization <> '' AND model_type <> '' AND access_type <> '')); + +CREATE OR REPLACE VIEW data_sources +AS +SELECT * +FROM data_sources_data ds +WHERE EXISTS( + SELECT 1 + FROM tenants_data_sources tds + WHERE tds.data_source_id = ds.id AND tds.tenant_id = current_setting('app.tenant_id')::BIGINT + ); + diff --git a/src/test/java/com/odysseusinc/arachne/portal/api/v1/controller/AchillesControllerTest.java b/src/test/java/com/odysseusinc/arachne/portal/api/v1/controller/AchillesControllerTest.java index 6a26e2e9a..2026603c0 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/api/v1/controller/AchillesControllerTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/api/v1/controller/AchillesControllerTest.java @@ -152,13 +152,13 @@ public void listReports() throws Exception { public void getFile() throws Exception { Bootstrap bootstrap = new Bootstrap(); - AchillesFile observationFile = achillesFileRepository.findOne(11L); + AchillesFile observationFile = achillesFileRepository.findById(11L).orElse(null); assertThat(observationFile, is(notNullValue())); observationFile.setData(bootstrap.observationJson()); - AchillesFile dashboardFile = achillesFileRepository.findOne(4L); + AchillesFile dashboardFile = achillesFileRepository.findById(4L).get(); assertThat(dashboardFile, is(notNullValue())); dashboardFile.setData(bootstrap.dashboardJson()); - achillesFileRepository.save(Arrays.asList(observationFile, dashboardFile)); + achillesFileRepository.saveAll(Arrays.asList(observationFile, dashboardFile)); mvc.perform(get(String.format(API_FILES, PUBLIC_DS, "dashboard.json")) .accept(MediaType.APPLICATION_JSON_UTF8)) diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/BaseDataSourceServiceTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/BaseDataSourceServiceTest.java index 8f9a00e2e..0baafd8ca 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/BaseDataSourceServiceTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/BaseDataSourceServiceTest.java @@ -46,8 +46,8 @@ public static Collection data() { @Test public void testSuggestionDataSourceDifferentCase() { //Arrange - Sort sort = new Sort(Sort.Direction.ASC, "name"); - PageRequest pageRequest = new PageRequest(0, 10, sort); + Sort sort = Sort.by(Sort.Direction.ASC, "name"); + PageRequest pageRequest = PageRequest.of(0, 10, sort); //Action Page pageWithMatchedDS = baseDataSourceService.suggestDataSource(checkingString, 0L, 2L, pageRequest); //Assert diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/UsersOperationsServiceTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/UsersOperationsServiceTest.java index 5e8af72e3..a00691aac 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/UsersOperationsServiceTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/UsersOperationsServiceTest.java @@ -11,7 +11,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.internal.util.collections.Sets; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; @@ -20,7 +20,7 @@ import static com.odysseusinc.arachne.portal.model.PortalConstants.TENANTS_USERS_TABLE_NAME; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -42,7 +42,7 @@ public class UsersOperationsServiceTest { private UsersOperationsServiceImpl usersOperationsService; @Before - public void setUp() throws Exception { + public void setUp() { userA = new RawUser(); userA.setId(1L); @@ -55,8 +55,6 @@ public void setUp() throws Exception { public void shouldDeleteUsersRecord() { final List users = Arrays.asList(userA, userB); - when(baseRawUserRepository.findByIdIn(any())).thenReturn(users); - when(baseRawUserRepository.checkIfUsersAreDeletable("1,2", TENANTS_USERS_TABLE_NAME)).thenReturn("1,2"); usersOperationsService.deleteAllUsers(users); diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/AnalysisFilesSavingServiceImplTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/AnalysisFilesSavingServiceImplTest.java index 451f477e0..9ad21f05e 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/AnalysisFilesSavingServiceImplTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/AnalysisFilesSavingServiceImplTest.java @@ -7,7 +7,7 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/AnalysesQueriesRendererTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/AnalysesQueriesRendererTest.java index ff1dff27e..ec36e393e 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/AnalysesQueriesRendererTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/AnalysesQueriesRendererTest.java @@ -8,13 +8,13 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.List; import static com.odysseusinc.arachne.portal.service.analysis.heracles.parts.HeraclesTestUtils.renameToSqlParameter; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/FinalizeAnalysisRendererTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/FinalizeAnalysisRendererTest.java index b095379f0..99928edf8 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/FinalizeAnalysisRendererTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/FinalizeAnalysisRendererTest.java @@ -4,7 +4,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static com.odysseusinc.arachne.portal.service.analysis.heracles.parts.HeraclesTestUtils.renameToSqlParameter; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/HeraclesAnalysesLoaderTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/HeraclesAnalysesLoaderTest.java index 8cbb5d29f..4760b9928 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/HeraclesAnalysesLoaderTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/HeraclesAnalysesLoaderTest.java @@ -3,7 +3,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Map; import java.util.Set; diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/InitHeraclesRendererTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/InitHeraclesRendererTest.java index bb11928b0..331ce60b8 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/InitHeraclesRendererTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/InitHeraclesRendererTest.java @@ -4,7 +4,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static com.odysseusinc.arachne.portal.service.analysis.heracles.parts.HeraclesTestUtils.renameToSqlParameter; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/SelectResultsQueryRendererTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/SelectResultsQueryRendererTest.java index 1f615516c..6015adb1c 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/SelectResultsQueryRendererTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/analysis/heracles/parts/SelectResultsQueryRendererTest.java @@ -6,7 +6,7 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/odysseusinc/arachne/portal/service/submission/impl/SubmissionServiceImplTest.java b/src/test/java/com/odysseusinc/arachne/portal/service/submission/impl/SubmissionServiceImplTest.java index f2b4b0e34..2621062f2 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/service/submission/impl/SubmissionServiceImplTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/service/submission/impl/SubmissionServiceImplTest.java @@ -15,7 +15,7 @@ import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; @@ -28,8 +28,11 @@ import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.anyList; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class SubmissionServiceImplTest { @@ -60,15 +63,19 @@ public class SubmissionServiceImplTest { private SubmissionServiceImpl submissionService; @Captor private ArgumentCaptor fileCaptor; + @Captor + private ArgumentCaptor stringCaptor; + @Captor + private ArgumentCaptor longCaptor; @Before - public void setUp(){ + public void setUp() { - when(submissionRepository.findById(any())).thenReturn(submission); + when(submissionRepository.getOne(any())).thenReturn(submission); when(securityContext.getAuthentication()).thenReturn(authentication); when(authentication.getPrincipal()).thenReturn(userDetails); - when(userService.getByUsername(anyString())).thenReturn(user); - when(contentStorageService.saveFile(any(),any(),any())).thenReturn(arachneFileMeta); + when(userService.getByUsername(any())).thenReturn(user); + when(contentStorageService.saveFile(any(), any(), any())).thenReturn(arachneFileMeta); SecurityContextHolder.setContext(securityContext); } @@ -80,8 +87,8 @@ public void shouldUploadFlatZipArchive() throws IOException { submissionService.uploadCompressedResultsByDataOwner(1L, new File(zipFileUrl.getPath())); - verify(contentStorageService, times(2)).saveFile(fileCaptor.capture(),anyString(),anyLong()); - verify(submissionResultFileRepository).save(anyList()); + verify(contentStorageService, times(2)).saveFile(fileCaptor.capture(), stringCaptor.capture(), longCaptor.capture()); + verify(submissionResultFileRepository).saveAll(anyList()); final List capturedFileNames = fileCaptor.getAllValues().stream().map(File::getName).collect(Collectors.toList()); assertThat(capturedFileNames).containsExactly("test2.txt", "test3.txt"); } @@ -96,7 +103,7 @@ public void shouldUploadZipArchivePreservingSubFolder() throws IOException { verify(contentStorageHelper).getResultFilesDir(submission, "output/test2.txt"); verify(contentStorageHelper).getResultFilesDir(submission, "output/test3.txt"); - verify(contentStorageService, times(2)).saveFile(fileCaptor.capture(),anyString(),anyLong()); + verify(contentStorageService, times(2)).saveFile(fileCaptor.capture(), stringCaptor.capture(), longCaptor.capture()); final List capturedFileNames = fileCaptor.getAllValues().stream().map(File::getName).collect(Collectors.toList()); assertThat(capturedFileNames).containsExactly("test2.txt", "test3.txt"); } diff --git a/src/test/java/com/odysseusinc/arachne/portal/util/AnalysisHelperTest.java b/src/test/java/com/odysseusinc/arachne/portal/util/AnalysisHelperTest.java index 06c38dd30..e6d765448 100644 --- a/src/test/java/com/odysseusinc/arachne/portal/util/AnalysisHelperTest.java +++ b/src/test/java/com/odysseusinc/arachne/portal/util/AnalysisHelperTest.java @@ -156,7 +156,7 @@ private Analysis prepareAnalysis(IUser author, Study study) throws Exception { List exists = analysisRepository.findByTitleAndStudyId("AnalysisHelperTest#test", study.getId()); if (!exists.isEmpty()) { - analysisRepository.delete(exists); + analysisRepository.deleteAll(exists); } Analysis analysis = new Analysis(); analysis.setTitle("AnalysisHelperTest#test"); @@ -200,7 +200,7 @@ private Study prepareStudy(IUser owner) throws NotUniqueException, NotExistExcep if (!exists.isEmpty()) { analysisFileRepository.deleteAll(); submissionFileRepository.deleteAll(); - studyRepository.delete(exists); + studyRepository.deleteAll(exists); } Study study = new Study(); study.setTitle("AnalysisHelperTest#test"); diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 5f5646ec3..760bc9548 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -4,16 +4,17 @@ server.ssl.enabled=false portal.urlWhiteList=http://localhost:0 portal.organizations.enableCreateByNonAdmin=true portal.notifyAdminAboutNewUser=true -flyway.datasource.driverClassName=${spring.datasource.driver-class-name} -flyway.datasource.url=${spring.datasource.url} -flyway.datasource.username=${spring.datasource.username} -flyway.datasource.password=${spring.datasource.password} -flyway.baseline-on-migrate=true -flyway.placeholderReplacement=false -flyway.out-of-order=true -flyway.validateOnMigrate=false - cache.enabled=false + +spring.main.allow-bean-definition-overriding=true +spring.flyway.datasource.driverClassName=${spring.datasource.driver-class-name} +spring.flyway.datasource.url=${spring.datasource.url} +spring.flyway.datasource.username=${spring.datasource.username} +spring.flyway.datasource.password=${spring.datasource.password} +spring.flyway.table=schema_version +spring.flyway.placeholderReplacement=false +spring.flyway.out-of-order=true +spring.flyway.validateOnMigrate=false spring.jpa.database=POSTGRESQL spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.show-sql=true @@ -22,12 +23,18 @@ spring.jpa.hibernate.connection.CharSet=utf8 spring.jpa.hibernate.connection.characterEncoding=utf8 spring.jpa.hibernate.connection.useUnicode=true spring.jpa.properties.hibernate.jdbc.batch_size=10 +spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/arachne_portal_test_@env@ spring.datasource.username=ohdsi spring.datasource.password=ohdsi spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.max-active=400 spring.datasource.connection-test-query=select 1 +spring.datasource.pool-name=Test-Pool + +management.endpoint.restart.enabled=true +management.health.ldap.enabled=false + arachne.token.secret=129DF19C8A91AFD8375A2826A33539K01ACQ778QOJFAA9MGWLWH73PLXVFVHBR7860MTIE2O8EEVF9KCO77P6A7NUNX4XHAGCRFSBWG879XPDOIN6C2LFCKJI002OIABS4D6Q9VMJJIX8UCE48EF arachne.token.header=Arachne-Auth-Token arachne.systemToken.header=Arachne-System-Token @@ -49,11 +56,11 @@ spring.mail.properties.mail.smtp.starttls.required= spring.mvc.view.prefix=/ spring.mvc.view.suffix=.html arachne.mail.notifier=odysseusinc.notifier@gmail.com -arachne.mail.signature: Regards,
Odysseus Data Services, Inc. -arachne.mail.app-title: Arachne +arachne.mail.signature=Regards,
Odysseus Data Services, Inc. +arachne.mail.app-title=Arachne spring.thymeleaf.enabled=false spring.cache.type=NONE -swagger.enable=true +swagger.enable=false build.number=@build.number@ build.id=@build.id@ project.version=@project.version@ @@ -61,8 +68,8 @@ project.version=@project.version@ files.store.path=/tmp/arachne/files files.store.jcr-path=/var/arachne/files/jcr files.stdout.name=stdout.txt -spring.http.multipart.max-file-size=128MB -spring.http.multipart.max-request-size=128MB +spring.servlet.multipart.max-file-size=128MB +spring.servlet.multipart.max-request-size=128MB analisis.file.maxsize=1048576 user.enabled.default=true @@ -90,6 +97,9 @@ spring.activemq.packages.trust-all=true jodconverter.local.enabled=false +jasypt.encryptor.algorithm=PBEWITHMD5ANDDES +jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator + # Available methods: DB, LDAP security.method=db