Skip to content

Commit df6e43c

Browse files
committed
TMS - Common DAO migration
1 parent 2ea10ef commit df6e43c

File tree

158 files changed

+20589
-2378
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+20589
-2378
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ hs_err_pid*
1919
build/
2020
.gradle/
2121
out/
22+
src/test/resources/db/migration/*.sql

project-properties.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ project.ext {
1616
isDebugMode = System.getProperty("DEBUG", "false") == "true"
1717
releaseMode = project.hasProperty("releaseMode") ? project.releaseMode.toBoolean() : false
1818
scriptsUrl = commonScriptsUrl + (releaseMode ? '5.14.0' : 'develop')
19-
migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.14.0' : 'develop')
19+
migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.14.0' : 'feature/EPMRPP-migrate-tms-to-develop')
2020
manifestSchemaUrl = schemaUrl + ('manifest.schema.json')
2121
//TODO refactor with archive download
2222
testScriptsSrc = [
@@ -92,6 +92,7 @@ project.ext {
9292
(migrationsUrl + '/migrations/209_add_activity_org_id.up.sql') : 'V209__add_activity_org_id.sql',
9393
(migrationsUrl + '/migrations/210_organization_settings_table.up.sql') : 'V210__organization_settings_table.sql',
9494
(migrationsUrl + '/migrations/212_update_default_users.up.sql') : 'V212__update_default_users.sql',
95+
(migrationsUrl + '/migrations/1000_tms_initial.up.sql') : 'V1000__tms_initial.up.sql',
9596
]
9697
excludeTests = ['**/entity/**',
9798
'**/aop/**',

src/main/java/com/epam/reportportal/core/configs/DataStoreConfiguration.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.epam.reportportal.infrastructure.persistence.filesystem.DataStore;
2424
import com.epam.reportportal.infrastructure.persistence.filesystem.LocalDataStore;
2525
import com.epam.reportportal.infrastructure.persistence.filesystem.distributed.s3.S3DataStore;
26+
import com.epam.reportportal.infrastructure.persistence.filesystem.tms.LocalTmsDataStore;
27+
import com.epam.reportportal.infrastructure.persistence.filesystem.tms.TmsDataStore;
2628
import com.epam.reportportal.infrastructure.persistence.util.FeatureFlagHandler;
2729
import com.google.common.base.Optional;
2830
import com.google.common.base.Supplier;
@@ -42,10 +44,12 @@
4244
import org.jclouds.rest.ConfiguresHttpApi;
4345
import org.jclouds.s3.S3Client;
4446
import org.springframework.beans.factory.annotation.Autowired;
47+
import org.springframework.beans.factory.annotation.Qualifier;
4548
import org.springframework.beans.factory.annotation.Value;
4649
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4750
import org.springframework.context.annotation.Bean;
4851
import org.springframework.context.annotation.Configuration;
52+
import org.springframework.context.annotation.Primary;
4953

5054
/**
5155
* @author Dzianis_Shybeka
@@ -137,6 +141,7 @@ public String toString() {
137141

138142
@Bean
139143
@ConditionalOnProperty(name = "datastore.type", havingValue = "filesystem")
144+
@Primary
140145
public BlobStore filesystemBlobStore(
141146
@Value("${datastore.path:/data/store}") String baseDirectory) {
142147

@@ -171,6 +176,7 @@ public DataStore localDataStore(@Autowired BlobStore blobStore,
171176
*/
172177
@Bean
173178
@ConditionalOnProperty(name = "datastore.type", havingValue = "s3-compatible")
179+
@Primary
174180
public BlobStore minioBlobStore(@Value("${datastore.accessKey}") String accessKey,
175181
@Value("${datastore.secretKey}") String secretKey,
176182
@Value("${datastore.endpoint}") String endpoint) {
@@ -213,6 +219,7 @@ public DataStore minioDataStore(@Autowired BlobStore blobStore,
213219
*/
214220
@Bean
215221
@ConditionalOnProperty(name = "datastore.type", havingValue = "aws-s3")
222+
@Primary
216223
public BlobStore s3BlobStore(
217224
@Value("${datastore.accessKey:}") String accessKey,
218225
@Value("${datastore.secretKey:}") String secretKey,
@@ -247,6 +254,33 @@ public DataStore s3DataStore(@Autowired BlobStore blobStore,
247254
);
248255
}
249256

257+
@Bean
258+
@ConditionalOnProperty(name = "rp.tms.datastore.type", havingValue = "filesystem")
259+
public BlobStore tmsFilesystemBlobStore(
260+
@Value("${rp.tms.datastore.path:/data/store}") String baseDirectory) {
261+
262+
Properties properties = new Properties();
263+
properties.setProperty(FilesystemConstants.PROPERTY_BASEDIR, baseDirectory);
264+
265+
BlobStoreContext blobStoreContext =
266+
ContextBuilder.newBuilder("filesystem").overrides(properties)
267+
.buildView(BlobStoreContext.class);
268+
269+
return blobStoreContext.getBlobStore();
270+
}
271+
272+
@Bean
273+
@ConditionalOnProperty(name = "rp.tms.datastore.type", havingValue = "filesystem")
274+
public TmsDataStore tmsLocalDataStore(
275+
@Autowired @Qualifier("tmsFilesystemBlobStore") BlobStore tmsFilesystemBlobStore,
276+
FeatureFlagHandler featureFlagHandler,
277+
@Value("${rp.tms.datastore.bucketPrefix:tms-prj-}") String bucketPrefix,
278+
@Value("${rp.tms.datastore.bucketPostfix:}") String bucketPostfix,
279+
@Value("${rp.tms.datastore.defaultBucketName:tms-rp-bucket}") String defaultBucketName) {
280+
return new LocalTmsDataStore(
281+
tmsFilesystemBlobStore, featureFlagHandler, bucketPrefix, bucketPostfix, defaultBucketName);
282+
}
283+
250284
@Bean("attachmentThumbnailator")
251285
public Thumbnailator attachmentThumbnailator(
252286
@Value("${datastore.thumbnail.attachment.width}") int width,
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.epam.reportportal.infrastructure.persistence.binary.tms;
2+
3+
import static java.util.Optional.ofNullable;
4+
5+
import com.epam.reportportal.infrastructure.commons.Thumbnailator;
6+
import com.epam.reportportal.infrastructure.persistence.filesystem.DataEncoder;
7+
import com.epam.reportportal.infrastructure.persistence.filesystem.tms.TmsDataStore;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.util.List;
11+
import java.util.Optional;
12+
import java.util.stream.Collectors;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
import org.springframework.beans.factory.annotation.Autowired;
16+
import org.springframework.beans.factory.annotation.Qualifier;
17+
import org.springframework.stereotype.Service;
18+
19+
/**
20+
* TMS Attachment Data Store Service for managing TMS-specific attachments. Uses dedicated TMS
21+
* DataStore bean to separate TMS attachments from regular attachments.
22+
*
23+
* @author ReportPortal Team
24+
*/
25+
@Service("tmsAttachmentDataStoreService")
26+
public class TmsAttachmentDataStoreService implements TmsDataStoreService {
27+
28+
private static final Logger LOGGER = LoggerFactory.getLogger(TmsAttachmentDataStoreService.class);
29+
30+
private final TmsDataStore dataStore;
31+
private final DataEncoder dataEncoder;
32+
private final Thumbnailator thumbnailator;
33+
34+
@Autowired
35+
public TmsAttachmentDataStoreService(
36+
TmsDataStore dataStore,
37+
DataEncoder dataEncoder,
38+
@Qualifier("attachmentThumbnailator") Thumbnailator thumbnailator) {
39+
this.dataEncoder = dataEncoder;
40+
this.dataStore = dataStore;
41+
this.thumbnailator = thumbnailator;
42+
}
43+
44+
@Override
45+
public String saveThumbnail(String fileName, InputStream data) {
46+
try {
47+
return dataEncoder.encode(dataStore.save(fileName, thumbnailator.createThumbnail(data)));
48+
} catch (IOException e) {
49+
LOGGER.error("TMS thumbnail is not created for file [{}]. Error:\n{}", fileName, e);
50+
}
51+
return null;
52+
}
53+
54+
@Override
55+
public String save(String fileName, InputStream data) {
56+
return dataEncoder.encode(dataStore.save(fileName, data));
57+
}
58+
59+
@Override
60+
public void delete(String fileId) {
61+
dataStore.delete(dataEncoder.decode(fileId));
62+
}
63+
64+
@Override
65+
public void deleteAll(List<String> fileIds, String bucketName) {
66+
dataStore.deleteAll(
67+
fileIds.stream().map(dataEncoder::decode).collect(Collectors.toList()), bucketName);
68+
}
69+
70+
@Override
71+
public void deleteContainer(String containerName) {
72+
dataStore.deleteContainer(containerName);
73+
}
74+
75+
@Override
76+
public Optional<InputStream> load(String fileId) {
77+
return ofNullable(dataStore.load(dataEncoder.decode(fileId)));
78+
}
79+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2019 EPAM Systems
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.epam.reportportal.infrastructure.persistence.binary.tms;
18+
19+
import java.io.InputStream;
20+
import java.util.List;
21+
import java.util.Optional;
22+
23+
/**
24+
* @author <a href="mailto:[email protected]">Ihar Kahadouski</a>
25+
*/
26+
public interface TmsDataStoreService {
27+
28+
String save(String fileName, InputStream data);
29+
30+
String saveThumbnail(String fileName, InputStream data);
31+
32+
void delete(String fileId);
33+
34+
void deleteAll(List<String> fileIds, String bucketName);
35+
36+
void deleteContainer(String containerName);
37+
38+
Optional<InputStream> load(String fileId);
39+
}

src/main/java/com/epam/reportportal/infrastructure/persistence/commons/querygen/Condition.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,37 @@ public Object castValue(CriteriaHolder criteriaHolder, String value, ErrorType e
603603
return castArray(criteriaHolder, value, errorType);
604604
}
605605
}
606+
},
607+
608+
/**
609+
* Full text search condition using PostgreSQL tsvector
610+
*/
611+
FULL_TEXT_SEARCH("fts") {
612+
@Override
613+
public org.jooq.Condition toCondition(FilterCondition filter, CriteriaHolder criteriaHolder) {
614+
this.validate(criteriaHolder, filter.getValue(), filter.isNegative(),
615+
INCORRECT_FILTER_PARAMETERS);
616+
return DSL.condition(
617+
"{0} @@ plainto_tsquery('simple', {1})",
618+
DSL.field(criteriaHolder.getAggregateCriteria()),
619+
DSL.val(filter.getValue())
620+
);
621+
}
622+
623+
@Override
624+
public void validate(CriteriaHolder criteriaHolder, String value, boolean isNegative,
625+
ErrorType errorType) {
626+
expect(criteriaHolder, filterForString()).verify(errorType, formattedSupplier(
627+
"Full text search condition applicable only for search_vector fields. Type of field is '{}'",
628+
criteriaHolder.getDataType().getSimpleName()
629+
));
630+
}
631+
632+
@Override
633+
public Object castValue(CriteriaHolder criteriaHolder, String value, ErrorType errorType) {
634+
// value cast is not required for full text search
635+
return value;
636+
}
606637
};
607638

608639
/*
@@ -612,6 +643,7 @@ public Object castValue(CriteriaHolder criteriaHolder, String value, ErrorType e
612643
public static final String CNT = "cnt.";
613644
public static final String HAS_FILTER = "has.";
614645
public static final String UNDR = "under.";
646+
public static final String FTS = "fts.";
615647

616648
public static final String VALUES_SEPARATOR = ",";
617649
public static final String TIMESTAMP_SEPARATOR = ";";

0 commit comments

Comments
 (0)