From 5f9551512c409eae04b51c5e9396d232cde30577 Mon Sep 17 00:00:00 2001 From: Sergey Korotaev Date: Sun, 17 Dec 2023 19:04:29 +0300 Subject: [PATCH] =?UTF-8?q?#29=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C=20=D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=20=D1=81=20=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B5=D0=B9=20long=20integ?= =?UTF-8?q?er=20=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qa/platform/dataset/model/AliasModel.java | 16 ++++-- .../dataset/repository/AliasRepository.java | 6 +-- .../dataset/service/AliasService.java | 8 +-- .../platform/mapper/dataset/AliasMapper.java | 11 ++++ .../rocksdb/RocksDbEntityConverter.java | 18 ++++++- .../qa/platform/rocksdb/key/CompoundKey.java | 12 +++++ .../sequence/AutoIncrementSequenceAspect.java | 53 +++++++++++++++---- .../rocksdb/sequence/SequenceGenerator.java | 4 +- 8 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 src/main/java/apps/amaralus/qa/platform/rocksdb/key/CompoundKey.java diff --git a/src/main/java/apps/amaralus/qa/platform/dataset/model/AliasModel.java b/src/main/java/apps/amaralus/qa/platform/dataset/model/AliasModel.java index 003f704..d35b842 100644 --- a/src/main/java/apps/amaralus/qa/platform/dataset/model/AliasModel.java +++ b/src/main/java/apps/amaralus/qa/platform/dataset/model/AliasModel.java @@ -1,19 +1,29 @@ package apps.amaralus.qa.platform.dataset.model; +import apps.amaralus.qa.platform.rocksdb.key.CompoundKey; import apps.amaralus.qa.platform.rocksdb.sequence.GeneratedSequence; import lombok.Data; +import lombok.Getter; +import lombok.Setter; import org.springframework.data.annotation.Id; import org.springframework.data.keyvalue.annotation.KeySpace; @Data @KeySpace("alias") -//todo сделать составной ключ name+project public class AliasModel { + @Id @GeneratedSequence("alias-sequence") - private long id; + private Key key; private String name; private long dataset; private String propertyName; - private String project; + + @Getter + @Setter + @CompoundKey + public static final class Key { + long id; + String project; + } } diff --git a/src/main/java/apps/amaralus/qa/platform/dataset/repository/AliasRepository.java b/src/main/java/apps/amaralus/qa/platform/dataset/repository/AliasRepository.java index 266c053..116b3da 100644 --- a/src/main/java/apps/amaralus/qa/platform/dataset/repository/AliasRepository.java +++ b/src/main/java/apps/amaralus/qa/platform/dataset/repository/AliasRepository.java @@ -8,9 +8,9 @@ public interface AliasRepository extends KeyValueRepository { - List findAllByProject(String project); + List findAllByKey_Project(String project); - Optional findByNameAndProject(String name, String project); + Optional findByNameAndKey_Project(String name, String project); - List findAllByNameAndProject(String name, String project); + List findAllByNameAndKey_Project(String name, String project); } diff --git a/src/main/java/apps/amaralus/qa/platform/dataset/service/AliasService.java b/src/main/java/apps/amaralus/qa/platform/dataset/service/AliasService.java index 757fc9e..207f72d 100644 --- a/src/main/java/apps/amaralus/qa/platform/dataset/service/AliasService.java +++ b/src/main/java/apps/amaralus/qa/platform/dataset/service/AliasService.java @@ -32,7 +32,7 @@ public Alias save(Alias alias) { public Alias updateAliasName(String newName, String oldName, String project) { - var alias = aliasRepository.findByNameAndProject(oldName, project) + var alias = aliasRepository.findByNameAndKey_Project(oldName, project) .map(aliasModel -> { aliasModel.setName(newName); return aliasRepository.save(aliasModel); @@ -43,15 +43,15 @@ public Alias updateAliasName(String newName, String oldName, String project) { } public void deleteAliasByName(String name, String project) { - aliasRepository.deleteAll(aliasRepository.findAllByNameAndProject(name, project)); + aliasRepository.deleteAll(aliasRepository.findAllByNameAndKey_Project(name, project)); } public void deleteAllByProject(String project) { - aliasRepository.deleteAll(aliasRepository.findAllByProject(project)); + aliasRepository.deleteAll(aliasRepository.findAllByKey_Project(project)); } public Optional getAliasByName(String aliasName, String project) { - return aliasRepository.findByNameAndProject(aliasName, project) + return aliasRepository.findByNameAndKey_Project(aliasName, project) .map(aliasMapper::mapToD); } } diff --git a/src/main/java/apps/amaralus/qa/platform/mapper/dataset/AliasMapper.java b/src/main/java/apps/amaralus/qa/platform/mapper/dataset/AliasMapper.java index 5fa28ee..0f0b8c6 100644 --- a/src/main/java/apps/amaralus/qa/platform/mapper/dataset/AliasMapper.java +++ b/src/main/java/apps/amaralus/qa/platform/mapper/dataset/AliasMapper.java @@ -4,8 +4,19 @@ import apps.amaralus.qa.platform.dataset.model.AliasModel; import apps.amaralus.qa.platform.mapper.GenericMapper; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.MappingConstants; @Mapper(componentModel = MappingConstants.ComponentModel.SPRING) public interface AliasMapper extends GenericMapper { + + @Override + @Mapping(target = "key.id", source = "id") + @Mapping(target = "key.project", source = "project") + AliasModel mapToM(Alias alias); + + @Override + @Mapping(target = "id", source = "key.id") + @Mapping(target = "project", source = "key.project") + Alias mapToD(AliasModel aliasModel); } diff --git a/src/main/java/apps/amaralus/qa/platform/rocksdb/RocksDbEntityConverter.java b/src/main/java/apps/amaralus/qa/platform/rocksdb/RocksDbEntityConverter.java index c9e96d3..0e466f3 100644 --- a/src/main/java/apps/amaralus/qa/platform/rocksdb/RocksDbEntityConverter.java +++ b/src/main/java/apps/amaralus/qa/platform/rocksdb/RocksDbEntityConverter.java @@ -1,5 +1,6 @@ package apps.amaralus.qa.platform.rocksdb; +import apps.amaralus.qa.platform.rocksdb.key.CompoundKey; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,7 +39,13 @@ else if (id instanceof Long l) return longToBytes(l); else if (id instanceof String s) return s.getBytes(StandardCharsets.UTF_8); - else + else if (id.getClass().isAnnotationPresent(CompoundKey.class)) { + try { + return mapper.writer().writeValueAsBytes(id); + } catch (JsonProcessingException e) { + throw new RocksDbRuntimeException(e); + } + } else throw new UnsupportedOperationException("Id type [" + id.getClass().getName() + "] is unsupported!"); } @@ -53,8 +60,15 @@ else if (idClass.isAssignableFrom(Long.TYPE)) return bytesToLong(bytes); else if (idClass.isAssignableFrom(String.class)) return new String(bytes, StandardCharsets.UTF_8); - else + else if (idClass.isAnnotationPresent(CompoundKey.class)) { + try { + return mapper.reader().readValue(bytes, idClass); + } catch (IOException e) { + throw new RocksDbRuntimeException(e); + } + } else throw new UnsupportedOperationException("Id type [" + idClass.getName() + "] is unsupported!"); + } private byte[] intToBytes(int data) { diff --git a/src/main/java/apps/amaralus/qa/platform/rocksdb/key/CompoundKey.java b/src/main/java/apps/amaralus/qa/platform/rocksdb/key/CompoundKey.java new file mode 100644 index 0000000..ef42c7a --- /dev/null +++ b/src/main/java/apps/amaralus/qa/platform/rocksdb/key/CompoundKey.java @@ -0,0 +1,12 @@ +package apps.amaralus.qa.platform.rocksdb.key; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; + +@Retention(RetentionPolicy.RUNTIME) +@Target(value = TYPE) +public @interface CompoundKey { +} diff --git a/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/AutoIncrementSequenceAspect.java b/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/AutoIncrementSequenceAspect.java index b1ff315..21cf86a 100644 --- a/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/AutoIncrementSequenceAspect.java +++ b/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/AutoIncrementSequenceAspect.java @@ -1,14 +1,18 @@ package apps.amaralus.qa.platform.rocksdb.sequence; +import apps.amaralus.qa.platform.rocksdb.key.CompoundKey; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.InvalidPropertyException; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.stereotype.Component; +import java.lang.reflect.Field; import java.util.Set; @Aspect @@ -20,7 +24,8 @@ public class AutoIncrementSequenceAspect { private final MappingContext mappingContext; private final Set> sequences; - public AutoIncrementSequenceAspect(SequenceGenerator sequenceGenerator, MappingContext mappingContext) { + public AutoIncrementSequenceAspect(SequenceGenerator sequenceGenerator, + MappingContext mappingContext) { this.sequenceGenerator = sequenceGenerator; this.mappingContext = mappingContext; sequences = sequenceGenerator.getSequencesClasses(); @@ -52,19 +57,45 @@ private void handleEntity(Object entity) { } } + @SneakyThrows @SuppressWarnings("java:S2589") private void incrementSequence(PersistentPropertyAccessor accessor, PersistentProperty persistentProperty) { var propertyValue = accessor.getProperty(persistentProperty); - // null or int or long equality - if (propertyValue == null || propertyValue.equals(0) || propertyValue.equals(0L)) { - long nextValue = sequenceGenerator.increment(getSequenceName(persistentProperty)); - - // possible int casting - if (persistentProperty.getType().equals(Integer.class) - || persistentProperty.getType().equals(Integer.TYPE)) - accessor.setProperty(persistentProperty, (int) nextValue); - else - accessor.setProperty(persistentProperty, nextValue); + + + if (propertyValue != null && propertyValue.getClass().isAnnotationPresent(CompoundKey.class)) { + incrementCompoundKey(persistentProperty, propertyValue); + } else { + if (propertyValue == null || propertyValue.equals(0) || propertyValue.equals(0L)) { + long nextValue = sequenceGenerator.increment(getSequenceName(persistentProperty)); + + // possible int casting + if (persistentProperty.getType().equals(Integer.class) + || persistentProperty.getType().equals(Integer.TYPE)) + accessor.setProperty(persistentProperty, (int) nextValue); + else + accessor.setProperty(persistentProperty, nextValue); + } + } + } + + @SuppressWarnings("java:S3011") + private void incrementCompoundKey(PersistentProperty persistentProperty, Object propertyValue) throws IllegalAccessException { + + for (Field field : propertyValue.getClass().getDeclaredFields()) { + + if (!field.getType().equals(Long.class) + && !field.getType().equals(Long.TYPE) + && !field.getType().equals(Integer.class) + && !field.getType().equals(Integer.TYPE)) + throw new InvalidPropertyException(persistentProperty.getOwner().getType(), persistentProperty.getName(), "Sequence only supports long or integer types"); + + field.setAccessible(true); + + field.set( + propertyValue, + sequenceGenerator.increment(getSequenceName(persistentProperty)) + ); } } diff --git a/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/SequenceGenerator.java b/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/SequenceGenerator.java index 14fff5d..e427412 100644 --- a/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/SequenceGenerator.java +++ b/src/main/java/apps/amaralus/qa/platform/rocksdb/sequence/SequenceGenerator.java @@ -1,6 +1,7 @@ package apps.amaralus.qa.platform.rocksdb.sequence; import apps.amaralus.qa.platform.rocksdb.RocksDbKeyValueAdapter; +import apps.amaralus.qa.platform.rocksdb.key.CompoundKey; import org.jetbrains.annotations.NotNull; import org.springframework.beans.InvalidPropertyException; import org.springframework.data.mapping.PersistentProperty; @@ -115,7 +116,8 @@ private void validateProperty(PersistentProperty persistentProperty) { if (!propertyType.equals(Long.class) && !propertyType.equals(Long.TYPE) && !propertyType.equals(Integer.class) - && !propertyType.equals(Integer.TYPE)) + && !propertyType.equals(Integer.TYPE) + && !propertyType.isAnnotationPresent(CompoundKey.class)) throw new InvalidPropertyException(sequenceClass, persistentProperty.getName(), "Sequence only supports long or integer types"); }