diff --git a/leia-core/pom.xml b/leia-core/pom.xml index d787511..30c34a3 100644 --- a/leia-core/pom.xml +++ b/leia-core/pom.xml @@ -61,6 +61,24 @@ aspectjrt org.aspectj + + + mockito-core + org.mockito + test + + + + mockito-junit-jupiter + org.mockito + test + + + + mockito-inline + org.mockito + test + diff --git a/leia-core/src/main/java/com/grookage/leia/core/ingestion/hub/SchemaProcessorHub.java b/leia-core/src/main/java/com/grookage/leia/core/ingestion/hub/SchemaProcessorHub.java index 10f31fc..02cecd4 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/ingestion/hub/SchemaProcessorHub.java +++ b/leia-core/src/main/java/com/grookage/leia/core/ingestion/hub/SchemaProcessorHub.java @@ -23,7 +23,6 @@ import com.grookage.leia.models.schema.engine.SchemaEvent; import com.grookage.leia.models.schema.engine.SchemaEventVisitor; import com.grookage.leia.repository.SchemaRepository; -import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import java.util.Arrays; @@ -31,13 +30,20 @@ import java.util.Optional; @Slf4j -@NoArgsConstructor public class SchemaProcessorHub { private final Map processors = Maps.newHashMap(); private SchemaRepository schemaRepository; private VersionIDGenerator versionIDGenerator; + private SchemaProcessorHub() { + + } + + public static SchemaProcessorHub of() { + return new SchemaProcessorHub(); + } + public SchemaProcessorHub withSchemaRepository(SchemaRepository schemaRepository) { Preconditions.checkNotNull(schemaRepository, "Schema Repository can't be null"); this.schemaRepository = schemaRepository; diff --git a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessor.java b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessor.java index 329c14e..e0fc69e 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessor.java +++ b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessor.java @@ -19,7 +19,6 @@ import com.grookage.leia.core.exception.LeiaErrorCode; import com.grookage.leia.core.exception.LeiaException; import com.grookage.leia.core.ingestion.utils.ContextUtils; -import com.grookage.leia.core.ingestion.utils.SchemaUtils; import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; import com.grookage.leia.models.schema.engine.SchemaContext; @@ -50,7 +49,7 @@ public void process(SchemaContext context) { final var schemaKey = context.getContext(SchemaKey.class) .orElseThrow((Supplier) () -> LeiaException.error(LeiaErrorCode.VALUE_NOT_FOUND)); final var storedSchema = getSchemaRepository().get(schemaKey).orElse(null); - if (null == storedSchema) { + if (null == storedSchema || storedSchema.getSchemaState() != SchemaState.CREATED) { log.error("There are no stored schemas present with namespace {}, version {} and schemaName {}. Please try updating them instead", schemaKey.getNamespace(), schemaKey.getVersion(), @@ -64,6 +63,6 @@ public void process(SchemaContext context) { storedSchema.getSchemaMeta().setUpdatedAt(System.currentTimeMillis()); storedSchema.setSchemaState(SchemaState.APPROVED); getSchemaRepository().update(storedSchema); - context.addContext(SchemaDetails.class.getSimpleName(), SchemaUtils.toSchemaDetails(storedSchema)); + context.addContext(SchemaDetails.class.getSimpleName(), storedSchema); } } diff --git a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessor.java b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessor.java index 14d4866..ea19eba 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessor.java +++ b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessor.java @@ -59,8 +59,8 @@ public void process(SchemaContext context) { } final var userName = ContextUtils.getUser(context); final var email = ContextUtils.getEmail(context); - final var storedSchema = SchemaUtils.toStoredSchema(createSchemaRequest, userName, email, getVersionIDGenerator()); - getSchemaRepository().create(storedSchema); - context.addContext(SchemaDetails.class.getSimpleName(), SchemaUtils.toSchemaDetails(storedSchema)); + final var schemaDetails = SchemaUtils.toSchemaDetails(createSchemaRequest, userName, email, getVersionIDGenerator()); + getSchemaRepository().create(schemaDetails); + context.addContext(SchemaDetails.class.getSimpleName(), schemaDetails); } } diff --git a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessor.java b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessor.java index eaa4ecf..03ef199 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessor.java +++ b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessor.java @@ -19,7 +19,6 @@ import com.grookage.leia.core.exception.LeiaErrorCode; import com.grookage.leia.core.exception.LeiaException; import com.grookage.leia.core.ingestion.utils.ContextUtils; -import com.grookage.leia.core.ingestion.utils.SchemaUtils; import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; import com.grookage.leia.models.schema.engine.SchemaContext; @@ -49,7 +48,7 @@ public void process(SchemaContext context) { final var schemaKey = context.getContext(SchemaKey.class) .orElseThrow((Supplier) () -> LeiaException.error(LeiaErrorCode.VALUE_NOT_FOUND)); final var storedSchema = getSchemaRepository().get(schemaKey).orElse(null); - if (null == storedSchema) { + if (null == storedSchema || storedSchema.getSchemaState() != SchemaState.CREATED) { log.error("There are no stored schemas present with namespace {}, version {} and schemaName {}. Please try updating them instead", schemaKey.getNamespace(), schemaKey.getVersion(), @@ -63,6 +62,6 @@ public void process(SchemaContext context) { storedSchema.getSchemaMeta().setUpdatedAt(System.currentTimeMillis()); storedSchema.setSchemaState(SchemaState.REJECTED); getSchemaRepository().update(storedSchema); - context.addContext(SchemaDetails.class.getSimpleName(), SchemaUtils.toSchemaDetails(storedSchema)); + context.addContext(SchemaDetails.class.getSimpleName(), storedSchema); } } diff --git a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessor.java b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessor.java index 7d8b138..b72e308 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessor.java +++ b/leia-core/src/main/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessor.java @@ -19,7 +19,6 @@ import com.grookage.leia.core.exception.LeiaErrorCode; import com.grookage.leia.core.exception.LeiaException; import com.grookage.leia.core.ingestion.utils.ContextUtils; -import com.grookage.leia.core.ingestion.utils.SchemaUtils; import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; import com.grookage.leia.models.schema.engine.SchemaContext; @@ -70,6 +69,8 @@ public void process(SchemaContext context) { storedSchema.getSchemaMeta().setCreatedBy(userName); storedSchema.getSchemaMeta().setCreatedByEmail(email); storedSchema.getSchemaMeta().setCreatedAt(System.currentTimeMillis()); - context.addContext(SchemaDetails.class.getSimpleName(), SchemaUtils.toSchemaDetails(storedSchema)); + storedSchema.setValidationType(updateSchemaRequest.getValidationType()); + storedSchema.setSchemaType(updateSchemaRequest.getSchemaType()); + context.addContext(SchemaDetails.class.getSimpleName(), storedSchema); } } diff --git a/leia-core/src/main/java/com/grookage/leia/core/ingestion/utils/SchemaUtils.java b/leia-core/src/main/java/com/grookage/leia/core/ingestion/utils/SchemaUtils.java index 7f292de..a3c1769 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/ingestion/utils/SchemaUtils.java +++ b/leia-core/src/main/java/com/grookage/leia/core/ingestion/utils/SchemaUtils.java @@ -19,28 +19,30 @@ import com.grookage.leia.core.ingestion.VersionIDGenerator; import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; +import com.grookage.leia.models.schema.SchemaMeta; import com.grookage.leia.models.schema.engine.SchemaState; import com.grookage.leia.models.schema.ingestion.CreateSchemaRequest; -import com.grookage.leia.models.storage.StoredSchema; -import com.grookage.leia.models.storage.StoredSchemaMeta; import lombok.experimental.UtilityClass; @UtilityClass public class SchemaUtils { - public StoredSchema toStoredSchema(final CreateSchemaRequest createSchemaRequest, - final String userName, - final String email, - final VersionIDGenerator versionIDGenerator) { - return StoredSchema.builder() - .schemaName(createSchemaRequest.getSchemaName()) - .namespace(createSchemaRequest.getNamespace()) - .versionId(versionIDGenerator.generateVersionId("V")) + public SchemaDetails toSchemaDetails(final CreateSchemaRequest createSchemaRequest, + final String userName, + final String email, + final VersionIDGenerator versionIDGenerator) { + return SchemaDetails.builder() + .schemaKey(SchemaKey.builder() + .namespace(createSchemaRequest.getNamespace()) + .schemaName(createSchemaRequest.getSchemaName()) + .version(versionIDGenerator.generateVersionId("V")) + .build() + ) .schemaState(SchemaState.CREATED) .schemaType(createSchemaRequest.getSchemaType()) .description(createSchemaRequest.getDescription()) .attributes(createSchemaRequest.getAttributes()) - .schemaMeta(StoredSchemaMeta.builder() + .schemaMeta(SchemaMeta.builder() .createdBy(userName) .createdByEmail(email) .createdAt(System.currentTimeMillis()) @@ -48,19 +50,4 @@ public StoredSchema toStoredSchema(final CreateSchemaRequest createSchemaRequest .validationType(createSchemaRequest.getValidationType()) .build(); } - - public SchemaDetails toSchemaDetails(final StoredSchema storedSchema) { - return SchemaDetails.builder() - .schemaState(storedSchema.getSchemaState()) - .description(storedSchema.getDescription()) - .attributes(storedSchema.getAttributes()) - .schemaKey(SchemaKey.builder() - .namespace(storedSchema.getNamespace()) - .schemaName(storedSchema.getSchemaName()) - .version(storedSchema.getVersionId()) - .build()) - .schemaType(storedSchema.getSchemaType()) - .validationType(storedSchema.getValidationType()) - .build(); - } } diff --git a/leia-core/src/main/java/com/grookage/leia/core/retrieval/RepositorySupplier.java b/leia-core/src/main/java/com/grookage/leia/core/retrieval/RepositorySupplier.java index d7a7aec..b3cc0d0 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/retrieval/RepositorySupplier.java +++ b/leia-core/src/main/java/com/grookage/leia/core/retrieval/RepositorySupplier.java @@ -16,7 +16,6 @@ package com.grookage.leia.core.retrieval; -import com.grookage.leia.core.ingestion.utils.SchemaUtils; import com.grookage.leia.models.schema.SchemaRegistry; import com.grookage.leia.provider.suppliers.LeiaSupplier; import com.grookage.leia.repository.SchemaRepository; @@ -42,7 +41,7 @@ public void stop() { @Override public SchemaRegistry get() { final var schemaDetails = schemaRepository.getSchemas( - Set.of(), Set.of(), SchemaUtils::toSchemaDetails); + Set.of(), Set.of()); final var registry = new SchemaRegistry(); schemaDetails.forEach(registry::add); return registry; diff --git a/leia-core/src/main/java/com/grookage/leia/core/retrieval/SchemaRetriever.java b/leia-core/src/main/java/com/grookage/leia/core/retrieval/SchemaRetriever.java index b1da1ee..2e5cae7 100644 --- a/leia-core/src/main/java/com/grookage/leia/core/retrieval/SchemaRetriever.java +++ b/leia-core/src/main/java/com/grookage/leia/core/retrieval/SchemaRetriever.java @@ -17,7 +17,6 @@ package com.grookage.leia.core.retrieval; import com.google.common.base.Preconditions; -import com.grookage.leia.core.ingestion.utils.SchemaUtils; import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; import com.grookage.leia.models.schema.engine.SchemaState; @@ -60,8 +59,7 @@ public Optional getSchemaDetails(final SchemaKey schemaKey) { if (null != cacheConfig && cacheConfig.isEnabled()) { return this.refresher.getConfiguration().getSchemaDetails(schemaKey); } else { - final var storedSchema = schemaRepository.get(schemaKey); - return storedSchema.map(SchemaUtils::toSchemaDetails); + return schemaRepository.get(schemaKey); } } @@ -69,8 +67,7 @@ public List getCurrentSchemaDetails(final Set namespaces) if (null != cacheConfig && cacheConfig.isEnabled()) { return this.refresher.getConfiguration().getSchemaDetails(namespaces); } else { - return schemaRepository.getSchemas(namespaces, Set.of(SchemaState.APPROVED), - SchemaUtils::toSchemaDetails); + return schemaRepository.getSchemas(namespaces, Set.of(SchemaState.APPROVED)); } } @@ -78,8 +75,7 @@ public List getAllSchemaDetails(final Set namespaces) { if (null != cacheConfig && cacheConfig.isEnabled()) { return this.refresher.getConfiguration().getAllSchemaDetails(namespaces); } else { - return schemaRepository.getSchemas(namespaces, Arrays.stream(SchemaState.values()).collect(Collectors.toSet()), - SchemaUtils::toSchemaDetails); + return schemaRepository.getSchemas(namespaces, Arrays.stream(SchemaState.values()).collect(Collectors.toSet())); } } } diff --git a/leia-core/src/test/java/com/grookage/leia/core/ingestion/SchemaIngestorTest.java b/leia-core/src/test/java/com/grookage/leia/core/ingestion/SchemaIngestorTest.java new file mode 100644 index 0000000..ea6c983 --- /dev/null +++ b/leia-core/src/test/java/com/grookage/leia/core/ingestion/SchemaIngestorTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.core.ingestion; + +import com.grookage.leia.core.exception.LeiaException; +import com.grookage.leia.core.ingestion.hub.SchemaProcessorHub; +import com.grookage.leia.core.ingestion.processors.SchemaProcessor; +import com.grookage.leia.core.stubs.StubbedSchemaUpdater; +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.schema.SchemaKey; +import com.grookage.leia.models.schema.engine.SchemaEvent; +import com.grookage.leia.models.schema.ingestion.CreateSchemaRequest; +import com.grookage.leia.models.schema.ingestion.UpdateSchemaRequest; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.Optional; + +class SchemaIngestorTest { + + private static SchemaProcessorHub schemaProcessorHub; + private static SchemaIngestor schemaIngestor; + private static final StubbedSchemaUpdater schemaUpdater = new StubbedSchemaUpdater(); + + @BeforeEach + void setup() { + schemaProcessorHub = Mockito.mock(SchemaProcessorHub.class); + schemaIngestor = new SchemaIngestor() + .withProcessorHub(schemaProcessorHub).build(); + + } + + @Test + @SneakyThrows + void testCreateSchemaNoProcessor() { + Mockito.when(schemaProcessorHub.getProcessor(Mockito.any(SchemaEvent.class))) + .thenReturn(Optional.empty()); + final var createSchemaRequest = ResourceHelper.getResource( + "schema/createSchemaRequest.json", + CreateSchemaRequest.class + ); + Assertions.assertNotNull(createSchemaRequest); + Assertions.assertThrows(LeiaException.class, () -> schemaIngestor.add(schemaUpdater, createSchemaRequest)); + } + + @Test + @SneakyThrows + void testCreateSchema() { + final var schemaProcessor = Mockito.mock(SchemaProcessor.class); + Mockito.when(schemaProcessorHub.getProcessor(Mockito.any(SchemaEvent.class))) + .thenReturn(Optional.of(schemaProcessor)); + final var createSchemaRequest = ResourceHelper.getResource( + "schema/createSchemaRequest.json", + CreateSchemaRequest.class + ); + Assertions.assertNotNull(createSchemaRequest); + schemaIngestor.add(schemaUpdater, createSchemaRequest); + Mockito.verify(schemaProcessor, Mockito.times(1)).process(Mockito.any()); + } + + @Test + @SneakyThrows + void testUpdateSchema() { + final var schemaProcessor = Mockito.mock(SchemaProcessor.class); + Mockito.when(schemaProcessorHub.getProcessor(Mockito.any(SchemaEvent.class))) + .thenReturn(Optional.of(schemaProcessor)); + final var updateSchemaRequest = ResourceHelper.getResource( + "schema/updateSchemaRequest.json", + UpdateSchemaRequest.class + ); + Assertions.assertNotNull(updateSchemaRequest); + schemaIngestor.update(schemaUpdater, updateSchemaRequest); + Mockito.verify(schemaProcessor, Mockito.times(1)).process(Mockito.any()); + } + + @Test + @SneakyThrows + void testApproveSchema() { + final var schemaProcessor = Mockito.mock(SchemaProcessor.class); + Mockito.when(schemaProcessorHub.getProcessor(Mockito.any(SchemaEvent.class))) + .thenReturn(Optional.of(schemaProcessor)); + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + Assertions.assertNotNull(schemaKey); + schemaIngestor.approve(schemaUpdater, schemaKey); + Mockito.verify(schemaProcessor, Mockito.times(1)).process(Mockito.any()); + } + + @Test + @SneakyThrows + void testRejectSchema() { + final var schemaProcessor = Mockito.mock(SchemaProcessor.class); + Mockito.when(schemaProcessorHub.getProcessor(Mockito.any(SchemaEvent.class))) + .thenReturn(Optional.of(schemaProcessor)); + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + Assertions.assertNotNull(schemaKey); + schemaIngestor.reject(schemaUpdater, schemaKey); + Mockito.verify(schemaProcessor, Mockito.times(1)).process(Mockito.any()); + } +} diff --git a/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessorTest.java b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessorTest.java new file mode 100644 index 0000000..4514cec --- /dev/null +++ b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/ApproveSchemaProcessorTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.core.ingestion.processors; + +import com.grookage.leia.core.exception.LeiaException; +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.schema.SchemaDetails; +import com.grookage.leia.models.schema.SchemaKey; +import com.grookage.leia.models.schema.engine.SchemaContext; +import com.grookage.leia.models.schema.engine.SchemaState; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.Optional; + +class ApproveSchemaProcessorTest extends SchemaProcessorTest { + @Override + SchemaProcessor getSchemaProcessor() { + return ApproveSchemaProcessor.builder() + .schemaRepository(getSchemaRepository()) + .versionIDGenerator(getGenerator()) + .build(); + } + + @Test + @SneakyThrows + void testSchemaApprovalsInvalid() { + final var schemaContext = new SchemaContext(); + final var schemaProcessor = getSchemaProcessor(); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.empty()); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + } + + @Test + @SneakyThrows + void testSchemaApprovalsNotCreatedState() { + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + schemaDetails.setSchemaState(SchemaState.REJECTED); + final var schemaContext = new SchemaContext(); + schemaContext.addContext(SchemaKey.class.getSimpleName(), schemaKey); + final var schemaProcessor = getSchemaProcessor(); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.of(schemaDetails)); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + } + + @Test + @SneakyThrows + void testSchemaApprovals() { + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + final var schemaContext = new SchemaContext(); + schemaContext.addContext(SchemaKey.class.getSimpleName(), schemaKey); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + final var schemaProcessor = getSchemaProcessor(); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.of(schemaDetails)); + schemaProcessor.process(schemaContext); + Assertions.assertEquals(SchemaState.APPROVED, schemaDetails.getSchemaState()); + Mockito.verify(getSchemaRepository(), Mockito.times(1)).update(Mockito.any(SchemaDetails.class)); + } +} diff --git a/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessorTest.java b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessorTest.java new file mode 100644 index 0000000..d75eb03 --- /dev/null +++ b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/CreateSchemaProcessorTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.core.ingestion.processors; + +import com.grookage.leia.core.exception.LeiaException; +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.schema.SchemaDetails; +import com.grookage.leia.models.schema.engine.SchemaContext; +import com.grookage.leia.models.schema.ingestion.CreateSchemaRequest; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.List; + +class CreateSchemaProcessorTest extends SchemaProcessorTest { + + @Override + SchemaProcessor getSchemaProcessor() { + return CreateSchemaProcessor.builder() + .versionIDGenerator(getGenerator()) + .schemaRepository(getSchemaRepository()) + .build(); + } + + @Test + @SneakyThrows + void testCreateSchema() { + final var schemaProcessor = getSchemaProcessor(); + final var schemaContext = new SchemaContext(); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + final var createSchemaRequest = ResourceHelper.getResource( + "schema/createSchemaRequest.json", + CreateSchemaRequest.class + ); + schemaContext.addContext(CreateSchemaRequest.class.getSimpleName(), createSchemaRequest); + Mockito.when(getSchemaRepository().get(Mockito.anyString(), Mockito.anyString())).thenReturn(List.of()); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + getSchemaProcessor().process(schemaContext); + Mockito.verify(getSchemaRepository(), Mockito.times(1)).create(Mockito.any(SchemaDetails.class)); + } + + @Test + @SneakyThrows + void testCreateSchemaAlreadyExists() { + final var schemaContext = new SchemaContext(); + final var schemaProcessor = getSchemaProcessor(); + final var createSchemaRequest = ResourceHelper.getResource( + "schema/createSchemaRequest.json", + CreateSchemaRequest.class + ); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + schemaContext.addContext(CreateSchemaRequest.class.getSimpleName(), createSchemaRequest); + Mockito.when(getSchemaRepository().get(Mockito.anyString(), Mockito.anyString())).thenReturn(List.of(schemaDetails)); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + } +} diff --git a/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessorTest.java b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessorTest.java new file mode 100644 index 0000000..7530ab2 --- /dev/null +++ b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/RejectSchemaProcessorTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.core.ingestion.processors; + +import com.grookage.leia.core.exception.LeiaException; +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.schema.SchemaDetails; +import com.grookage.leia.models.schema.SchemaKey; +import com.grookage.leia.models.schema.engine.SchemaContext; +import com.grookage.leia.models.schema.engine.SchemaState; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.Optional; + +public class RejectSchemaProcessorTest extends SchemaProcessorTest { + @Override + SchemaProcessor getSchemaProcessor() { + return RejectSchemaProcessor.builder() + .schemaRepository(getSchemaRepository()) + .versionIDGenerator(getGenerator()) + .build(); + } + + @Test + @SneakyThrows + void testSchemaRejectionsInvalid() { + final var schemaContext = new SchemaContext(); + final var schemaProcessor = getSchemaProcessor(); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.empty()); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + } + + @Test + @SneakyThrows + void testSchemaRejectionsNotCreatedState() { + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + schemaDetails.setSchemaState(SchemaState.APPROVED); + final var schemaContext = new SchemaContext(); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + schemaContext.addContext(SchemaKey.class.getSimpleName(), schemaKey); + final var schemaProcessor = getSchemaProcessor(); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.of(schemaDetails)); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + } + + @Test + @SneakyThrows + void testSchemaRejections() { + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + schemaDetails.setSchemaState(SchemaState.CREATED); + final var schemaContext = new SchemaContext(); + schemaContext.addContext(SchemaKey.class.getSimpleName(), schemaKey); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + final var schemaProcessor = getSchemaProcessor(); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.of(schemaDetails)); + schemaProcessor.process(schemaContext); + Assertions.assertEquals(SchemaState.REJECTED, schemaDetails.getSchemaState()); + Mockito.verify(getSchemaRepository(), Mockito.times(1)).update(Mockito.any(SchemaDetails.class)); + } + +} diff --git a/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/SchemaProcessorTest.java b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/SchemaProcessorTest.java new file mode 100644 index 0000000..842ccc3 --- /dev/null +++ b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/SchemaProcessorTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.core.ingestion.processors; + +import com.grookage.leia.core.ingestion.VersionIDGenerator; +import com.grookage.leia.repository.SchemaRepository; +import lombok.Getter; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.Mockito; + +public abstract class SchemaProcessorTest { + + @Getter + private static SchemaRepository schemaRepository; + private static SchemaProcessor schemaProcessor; + + @Getter + private static final VersionIDGenerator generator = new VersionIDGenerator() { + @Override + public String generateVersionId(String prefix) { + return "V1234"; + } + }; + + abstract SchemaProcessor getSchemaProcessor(); + + @BeforeEach + void setup() { + schemaRepository = Mockito.mock(SchemaRepository.class); + schemaProcessor = getSchemaProcessor(); + } + +} diff --git a/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessorTest.java b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessorTest.java new file mode 100644 index 0000000..36941bc --- /dev/null +++ b/leia-core/src/test/java/com/grookage/leia/core/ingestion/processors/UpdateSchemaProcessorTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.core.ingestion.processors; + +import com.grookage.leia.core.exception.LeiaException; +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.schema.SchemaDetails; +import com.grookage.leia.models.schema.SchemaKey; +import com.grookage.leia.models.schema.engine.SchemaContext; +import com.grookage.leia.models.schema.ingestion.UpdateSchemaRequest; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.Optional; + + +class UpdateSchemaProcessorTest extends SchemaProcessorTest { + + @Test + @SneakyThrows + void testUpdateSchemas() { + final var schemaContext = new SchemaContext(); + final var schemaProcessor = getSchemaProcessor(); + final var schemaRequest = ResourceHelper.getResource( + "schema/updateSchemaRequest.json", + UpdateSchemaRequest.class + ); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + schemaContext.addContext(UpdateSchemaRequest.class.getSimpleName(), schemaRequest); + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.of(schemaDetails)); + schemaProcessor.process(schemaContext); + Mockito.verify(getSchemaRepository(), Mockito.times(1)).update(Mockito.any(SchemaDetails.class)); + } + + @Test + @SneakyThrows + void testUpdateSchemasNoDetails() { + final var schemaContext = new SchemaContext(); + final var schemaProcessor = getSchemaProcessor(); + final var schemaRequest = ResourceHelper.getResource( + "schema/updateSchemaRequest.json", + UpdateSchemaRequest.class + ); + schemaContext.addContext("USER", "testUser"); + schemaContext.addContext("EMAIL", "testEmail"); + schemaContext.addContext(UpdateSchemaRequest.class.getSimpleName(), schemaRequest); + Mockito.when(getSchemaRepository().get(Mockito.any(SchemaKey.class))).thenReturn(Optional.empty()); + Assertions.assertThrows(LeiaException.class, () -> schemaProcessor.process(schemaContext)); + } + + @Override + SchemaProcessor getSchemaProcessor() { + return UpdateSchemaProcessor.builder() + .versionIDGenerator(getGenerator()) + .schemaRepository(getSchemaRepository()) + .build(); + } +} diff --git a/leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/RemoveSchemaRequest.java b/leia-core/src/test/java/com/grookage/leia/core/stubs/StubbedSchemaUpdater.java similarity index 69% rename from leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/RemoveSchemaRequest.java rename to leia-core/src/test/java/com/grookage/leia/core/stubs/StubbedSchemaUpdater.java index 60abb1d..938c638 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/RemoveSchemaRequest.java +++ b/leia-core/src/test/java/com/grookage/leia/core/stubs/StubbedSchemaUpdater.java @@ -14,24 +14,24 @@ * limitations under the License. */ -package com.grookage.leia.models.schema.ingestion; +package com.grookage.leia.core.stubs; -import lombok.AllArgsConstructor; +import com.grookage.leia.models.user.SchemaUpdater; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotBlank; - -@Builder -@AllArgsConstructor @NoArgsConstructor +@Builder @Data -public class RemoveSchemaRequest { - @NotBlank - private String namespace; - @NotBlank - private String version; - @NotBlank - private String schemaName; +public class StubbedSchemaUpdater implements SchemaUpdater { + @Override + public String name() { + return "name"; + } + + @Override + public String email() { + return "name@grookage.com"; + } } diff --git a/leia-dropwizard/src/main/java/com/grookage/leia/dropwizard/bundle/LeiaBundle.java b/leia-dropwizard/src/main/java/com/grookage/leia/dropwizard/bundle/LeiaBundle.java index 1d8ea0e..84cb803 100644 --- a/leia-dropwizard/src/main/java/com/grookage/leia/dropwizard/bundle/LeiaBundle.java +++ b/leia-dropwizard/src/main/java/com/grookage/leia/dropwizard/bundle/LeiaBundle.java @@ -69,7 +69,7 @@ protected List withLifecycleManagers(T configuration) { public void run(T configuration, Environment environment) { final var userResolver = userResolver(configuration); Preconditions.checkNotNull(userResolver, "User Resolver can't be null"); - final var schemaProcessorHub = new SchemaProcessorHub() + final var schemaProcessorHub = SchemaProcessorHub.of() .withSchemaRepository(getSchemaRepository(configuration)) .withVersionIDGenerator(getVersionIDGenerator()) .build(); diff --git a/leia-elastic/src/main/java/com/grookage/leia/elastic/repository/ElasticRepository.java b/leia-elastic/src/main/java/com/grookage/leia/elastic/repository/ElasticRepository.java index 3c28b4d..497addd 100644 --- a/leia-elastic/src/main/java/com/grookage/leia/elastic/repository/ElasticRepository.java +++ b/leia-elastic/src/main/java/com/grookage/leia/elastic/repository/ElasticRepository.java @@ -37,7 +37,6 @@ import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; import com.grookage.leia.models.schema.engine.SchemaState; -import com.grookage.leia.models.storage.StoredSchema; import com.grookage.leia.repository.AbstractSchemaRepository; import lombok.Getter; import lombok.SneakyThrows; @@ -45,7 +44,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; @Getter @@ -90,7 +88,7 @@ private void initialize() { @Override @SneakyThrows - public void create(StoredSchema schema) { + public void create(SchemaDetails schema) { final var createDocument = new IndexRequest.Builder<>().document(schema) .index(SCHEMA_INDEX) .refresh(Refresh.WaitFor) @@ -102,7 +100,7 @@ public void create(StoredSchema schema) { @Override @SneakyThrows - public void update(StoredSchema schema) { + public void update(SchemaDetails schema) { final var updateRequest = new UpdateRequest.Builder<>() .index(SCHEMA_INDEX) .id(schema.getReferenceId()) @@ -110,12 +108,12 @@ public void update(StoredSchema schema) { .refresh(Refresh.WaitFor) .timeout(Time.of(s -> s.time(elasticConfig.getTimeout()))) .build(); - client.update(updateRequest, StoredSchema.class); + client.update(updateRequest, SchemaDetails.class); } @Override @SneakyThrows - public List get(String namespace, String schemaName) { + public List get(String namespace, String schemaName) { final var searchQuery = BoolQuery.of(t -> t.must(List.of( TermQuery.of(p -> p.field(NAMESPACE).value(namespace))._toQuery(), TermQuery.of(q -> q.field(SCHEMA_NAME).value(schemaName))._toQuery() @@ -126,7 +124,7 @@ public List get(String namespace, String schemaName) { .index(List.of(SCHEMA_INDEX)) .size(elasticConfig.getMaxResultSize()) //If you have more than 10K schemas, this will hold you up! .timeout(elasticConfig.getTimeout())), - StoredSchema.class + SchemaDetails.class ); return searchResponse.hits().hits().stream() .map(Hit::source).collect(Collectors.toList()); @@ -134,16 +132,15 @@ public List get(String namespace, String schemaName) { @Override @SneakyThrows - public Optional get(SchemaKey schemaKey) { - final var getResponse = client.get(GetRequest.of(request -> request.index(SCHEMA_INDEX).id(schemaKey.getReferenceId())), StoredSchema.class); + public Optional get(SchemaKey schemaKey) { + final var getResponse = client.get(GetRequest.of(request -> request.index(SCHEMA_INDEX).id(schemaKey.getReferenceId())), SchemaDetails.class); return Optional.ofNullable(getResponse.source()); } @Override @SneakyThrows public List getSchemas(final Set namespaces, - final Set schemaStates, - final Function mutator) { + final Set schemaStates) { final var namespaceQuery = namespaces.isEmpty() ? TermsQuery.of(q -> q)._toQuery() : TermsQuery.of(q -> q.field(NAMESPACE).terms(t -> t.value(getNormalizedValues(namespaces)) @@ -159,9 +156,8 @@ public List getSchemas(final Set namespaces, .index(List.of(SCHEMA_INDEX)) .size(elasticConfig.getMaxResultSize()) //If you have more than 10K schemas, this will hold you up! .timeout(elasticConfig.getTimeout())), - StoredSchema.class + SchemaDetails.class ); - return searchResponse.hits().hits().stream() - .map(hit -> mutator.apply(hit.source())).toList(); + return searchResponse.hits().hits().stream().map(Hit::source).toList(); } } diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/ArrayAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/ArrayAttribute.java index 3ed2da6..0aabd02 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/ArrayAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/ArrayAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class ArrayAttribute extends SchemaAttribute { public ArrayAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/BooleanAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/BooleanAttribute.java index a629ffb..89aa779 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/BooleanAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/BooleanAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class BooleanAttribute extends SchemaAttribute { public BooleanAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/ByteAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/ByteAttribute.java index 51bf763..5ecc453 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/ByteAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/ByteAttribute.java @@ -17,8 +17,16 @@ package com.grookage.leia.models.attributes; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.grookage.leia.models.qualifiers.QualifierInfo; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +@EqualsAndHashCode(callSuper = true) +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class ByteAttribute extends SchemaAttribute { public ByteAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/DoubleAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/DoubleAttribute.java index ee66e67..a454771 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/DoubleAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/DoubleAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class DoubleAttribute extends SchemaAttribute { public DoubleAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/EnumAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/EnumAttribute.java index fc0c2c6..591d22a 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/EnumAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/EnumAttribute.java @@ -20,15 +20,17 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import java.util.Set; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class EnumAttribute extends SchemaAttribute { - private final Set values; + private Set values; public EnumAttribute(final String name, final boolean optional, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/FloatAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/FloatAttribute.java index 9ad5d2c..85ed563 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/FloatAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/FloatAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class FloatAttribute extends SchemaAttribute { public FloatAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/IntegerAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/IntegerAttribute.java index 6c2b50e..a3be7d8 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/IntegerAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/IntegerAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class IntegerAttribute extends SchemaAttribute { public IntegerAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/LongAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/LongAttribute.java index 7f18a87..b1efa0c 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/LongAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/LongAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class LongAttribute extends SchemaAttribute { public LongAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/MapAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/MapAttribute.java index fe0a68e..c4af4c3 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/MapAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/MapAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class MapAttribute extends SchemaAttribute { public MapAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/ObjectAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/ObjectAttribute.java index cbcbf0c..65ef7e0 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/ObjectAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/ObjectAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class ObjectAttribute extends SchemaAttribute { public ObjectAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/SchemaAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/SchemaAttribute.java index 1df66a3..df99005 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/SchemaAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/SchemaAttribute.java @@ -30,7 +30,7 @@ @NoArgsConstructor @AllArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "allocationType", visible = true) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true) @JsonSubTypes({ @JsonSubTypes.Type(value = ArrayAttribute.class, name = "ARRAY"), @JsonSubTypes.Type(value = BooleanAttribute.class, name = "BOOLEAN"), diff --git a/leia-models/src/main/java/com/grookage/leia/models/attributes/StringAttribute.java b/leia-models/src/main/java/com/grookage/leia/models/attributes/StringAttribute.java index 65b31a6..ee768ac 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/attributes/StringAttribute.java +++ b/leia-models/src/main/java/com/grookage/leia/models/attributes/StringAttribute.java @@ -20,10 +20,12 @@ import com.grookage.leia.models.qualifiers.QualifierInfo; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; @EqualsAndHashCode(callSuper = true) @Data @JsonIgnoreProperties(ignoreUnknown = true) +@NoArgsConstructor public class StringAttribute extends SchemaAttribute { public StringAttribute(final String name, diff --git a/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaDetails.java b/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaDetails.java index 67a6515..6375d0a 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaDetails.java +++ b/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaDetails.java @@ -18,12 +18,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.google.common.base.Joiner; import com.grookage.leia.models.attributes.SchemaAttribute; import com.grookage.leia.models.schema.engine.SchemaState; -import com.grookage.leia.models.storage.StoredSchemaMeta; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -32,13 +34,15 @@ @AllArgsConstructor @Data @Builder +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class SchemaDetails { @NotNull SchemaKey schemaKey; String description; @NotNull SchemaState schemaState; - SchemaType schemaType; - SchemaValidationType validationType; - @NotNull StoredSchemaMeta schemaMeta; + @NotNull SchemaType schemaType; + SchemaValidationType validationType = SchemaValidationType.MATCHING; + @NotNull SchemaMeta schemaMeta; @NotEmpty Set attributes; @JsonIgnore @@ -49,4 +53,13 @@ public boolean match(final SchemaKey thatKey) { public boolean hasAttribute(final String name) { return attributes != null && attributes.stream().anyMatch(each -> each.getName().equalsIgnoreCase(name)); } + + @JsonIgnore + public String getReferenceId() { + return Joiner.on(":").join( + schemaKey.getNamespace(), + schemaKey.getSchemaName(), + schemaKey.getVersion() + ); + } } diff --git a/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaKey.java b/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaKey.java index e1a98a4..f6d2497 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaKey.java +++ b/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaKey.java @@ -17,18 +17,22 @@ package com.grookage.leia.models.schema; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.google.common.base.Joiner; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Builder @AllArgsConstructor @Data +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class SchemaKey { - private final String namespace; - private final String schemaName; - private final String version; + private String namespace; + private String schemaName; + private String version; @JsonIgnore public String getReferenceId() { diff --git a/leia-models/src/main/java/com/grookage/leia/models/storage/StoredSchemaMeta.java b/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaMeta.java similarity index 85% rename from leia-models/src/main/java/com/grookage/leia/models/storage/StoredSchemaMeta.java rename to leia-models/src/main/java/com/grookage/leia/models/schema/SchemaMeta.java index db81c88..2f0f7ef 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/storage/StoredSchemaMeta.java +++ b/leia-models/src/main/java/com/grookage/leia/models/schema/SchemaMeta.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.grookage.leia.models.storage; +package com.grookage.leia.models.schema; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -27,7 +28,8 @@ @NoArgsConstructor @Data @Builder -public class StoredSchemaMeta { +@JsonIgnoreProperties(ignoreUnknown = true) +public class SchemaMeta { @NotEmpty private String createdBy; private String createdByEmail; diff --git a/leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/UpdateSchemaRequest.java b/leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/UpdateSchemaRequest.java index a213885..1e6c0e0 100644 --- a/leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/UpdateSchemaRequest.java +++ b/leia-models/src/main/java/com/grookage/leia/models/schema/ingestion/UpdateSchemaRequest.java @@ -17,6 +17,8 @@ package com.grookage.leia.models.schema.ingestion; import com.grookage.leia.models.attributes.SchemaAttribute; +import com.grookage.leia.models.schema.SchemaType; +import com.grookage.leia.models.schema.SchemaValidationType; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -39,6 +41,8 @@ public class UpdateSchemaRequest { @NotBlank private String version; private String description; + private SchemaValidationType validationType; + private SchemaType schemaType; @NotEmpty private Set attributes; } diff --git a/leia-models/src/main/java/com/grookage/leia/models/storage/StoredSchema.java b/leia-models/src/main/java/com/grookage/leia/models/storage/StoredSchema.java deleted file mode 100644 index fc4308a..0000000 --- a/leia-models/src/main/java/com/grookage/leia/models/storage/StoredSchema.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2024. Koushik R . - * - * 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. - */ - -package com.grookage.leia.models.storage; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.google.common.base.Joiner; -import com.grookage.leia.models.attributes.SchemaAttribute; -import com.grookage.leia.models.schema.SchemaType; -import com.grookage.leia.models.schema.SchemaValidationType; -import com.grookage.leia.models.schema.engine.SchemaState; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.Set; - -@AllArgsConstructor -@NoArgsConstructor -@Data -@Builder -public class StoredSchema { - @NotEmpty - private String versionId; - @NotNull - private SchemaType schemaType; - @NotNull - private SchemaValidationType validationType; - @NotEmpty - private String namespace; - @NotEmpty - private String schemaName; - private String description; - private SchemaState schemaState; - @NotNull - private StoredSchemaMeta schemaMeta; - @NotEmpty - private Set attributes; - - @JsonIgnore - public String getReferenceId() { - return Joiner.on(".").join(namespace, schemaName, versionId); - } -} diff --git a/leia-models/src/test/java/com/grookage/leia/models/ResourceHelper.java b/leia-models/src/test/java/com/grookage/leia/models/ResourceHelper.java new file mode 100644 index 0000000..9119277 --- /dev/null +++ b/leia-models/src/test/java/com/grookage/leia/models/ResourceHelper.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.models; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Getter; + +import java.io.IOException; + +public class ResourceHelper { + + @Getter + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static T getResource(String path, Class klass) throws IOException { + objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + final var data = ResourceHelper.class.getClassLoader().getResourceAsStream(path); + return objectMapper.readValue(data, klass); + } + + public static T getResource(String path, TypeReference klass) throws IOException { + objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + final var data = ResourceHelper.class.getClassLoader().getResourceAsStream(path); + return objectMapper.readValue(data, klass); + } + +} diff --git a/leia-models/src/test/java/com/grookage/leia/models/attributes/AttributeTest.java b/leia-models/src/test/java/com/grookage/leia/models/attributes/AttributeTest.java new file mode 100644 index 0000000..7d12b02 --- /dev/null +++ b/leia-models/src/test/java/com/grookage/leia/models/attributes/AttributeTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.models.attributes; + +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.qualifiers.QualifierType; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class AttributeTest { + + @Test + @SneakyThrows + void testAttributeStructures() { + var attribute = ResourceHelper.getResource("attributes/attribute.json", SchemaAttribute.class); + Assertions.assertNotNull(attribute); + Assertions.assertEquals("testAttribute", attribute.getName()); + Assertions.assertSame(DataType.ARRAY, attribute.getType()); + attribute = ResourceHelper.getResource("attributes/enumAttribute.json", SchemaAttribute.class); + Assertions.assertNotNull(attribute); + Assertions.assertEquals("testAttribute", attribute.getName()); + Assertions.assertSame(DataType.ENUM, attribute.getType()); + Assertions.assertTrue(((EnumAttribute) attribute).getValues().contains("TEST_ENUM")); + attribute = ResourceHelper.getResource("attributes/attributeWithQualifier.json", SchemaAttribute.class); + Assertions.assertNotNull(attribute); + Assertions.assertEquals("testAttribute", attribute.getName()); + Assertions.assertSame(DataType.ARRAY, attribute.getType()); + Assertions.assertTrue(attribute.getQualifierInfo() != null && attribute.getQualifierInfo().getType() == QualifierType.PII); + } +} diff --git a/leia-models/src/test/java/com/grookage/leia/models/qualifiers/QualifierTest.java b/leia-models/src/test/java/com/grookage/leia/models/qualifiers/QualifierTest.java new file mode 100644 index 0000000..f99b881 --- /dev/null +++ b/leia-models/src/test/java/com/grookage/leia/models/qualifiers/QualifierTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.models.qualifiers; + +import com.grookage.leia.models.ResourceHelper; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class QualifierTest { + + @Test + @SneakyThrows + void testAttributeStructures() { + var qualifierInfo = ResourceHelper.getResource("qualifiers/piiQualifier.json", QualifierInfo.class); + Assertions.assertNotNull(qualifierInfo); + Assertions.assertSame(QualifierType.PII, qualifierInfo.getType()); + } +} diff --git a/leia-models/src/test/java/com/grookage/leia/models/request/NamespaceRequestTest.java b/leia-models/src/test/java/com/grookage/leia/models/request/NamespaceRequestTest.java new file mode 100644 index 0000000..bb23c7a --- /dev/null +++ b/leia-models/src/test/java/com/grookage/leia/models/request/NamespaceRequestTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.models.request; + +import com.grookage.leia.models.ResourceHelper; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class NamespaceRequestTest { + + @Test + @SneakyThrows + void testNamespaceRequest() { + final var namespaceRequest = ResourceHelper.getResource("request/namespaceRequest.json", NamespaceRequest.class); + Assertions.assertNotNull(namespaceRequest); + Assertions.assertTrue(namespaceRequest.getNamespaces().contains("test")); + } +} diff --git a/leia-models/src/test/java/com/grookage/leia/models/schema/SchemaDetailsTest.java b/leia-models/src/test/java/com/grookage/leia/models/schema/SchemaDetailsTest.java new file mode 100644 index 0000000..54cf6ee --- /dev/null +++ b/leia-models/src/test/java/com/grookage/leia/models/schema/SchemaDetailsTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.models.schema; + +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.attributes.DataType; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class SchemaDetailsTest { + @Test + @SneakyThrows + void testSchemaDetails() { + final var schemaDetails = ResourceHelper + .getResource("schema/schemaDetails.json", SchemaDetails.class); + Assertions.assertNotNull(schemaDetails); + final var schemaKey = schemaDetails.getSchemaKey(); + Assertions.assertNotNull(schemaKey); + Assertions.assertEquals("testNamespace", schemaKey.getNamespace()); + Assertions.assertEquals("testSchema", schemaKey.getSchemaName()); + Assertions.assertEquals("V1234", schemaKey.getVersion()); + final var schemaMeta = schemaDetails.getSchemaMeta(); + Assertions.assertNotNull(schemaMeta); + Assertions.assertEquals("testUser", schemaMeta.getCreatedBy()); + final var schemaAttributes = schemaDetails.getAttributes(); + Assertions.assertNotNull(schemaAttributes); + Assertions.assertTrue(schemaAttributes.stream().anyMatch(each -> each.getType() == DataType.ARRAY)); + Assertions.assertTrue(schemaAttributes.stream().anyMatch(each -> each.getType() == DataType.ENUM)); + Assertions.assertTrue(schemaAttributes.stream().noneMatch(each -> each.getType() == DataType.INTEGER)); + } +} diff --git a/leia-models/src/test/java/com/grookage/leia/models/schema/ingestion/IngestionRequestTest.java b/leia-models/src/test/java/com/grookage/leia/models/schema/ingestion/IngestionRequestTest.java new file mode 100644 index 0000000..374b9ef --- /dev/null +++ b/leia-models/src/test/java/com/grookage/leia/models/schema/ingestion/IngestionRequestTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024. Koushik R . + * + * 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. + */ + +package com.grookage.leia.models.schema.ingestion; + +import com.grookage.leia.models.ResourceHelper; +import com.grookage.leia.models.attributes.DataType; +import com.grookage.leia.models.schema.SchemaKey; +import com.grookage.leia.models.schema.SchemaType; +import com.grookage.leia.models.schema.SchemaValidationType; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class IngestionRequestTest { + + @Test + @SneakyThrows + void testIngestionRequests() { + final var createSchemaRequest = ResourceHelper.getResource( + "schema/createSchemaRequest.json", + CreateSchemaRequest.class + ); + Assertions.assertNotNull(createSchemaRequest); + var schemaAttributes = createSchemaRequest.getAttributes(); + Assertions.assertNotNull(schemaAttributes); + Assertions.assertTrue(schemaAttributes.stream().anyMatch(each -> each.getType() == DataType.ARRAY)); + Assertions.assertTrue(schemaAttributes.stream().noneMatch(each -> each.getType() == DataType.ENUM)); + Assertions.assertTrue(schemaAttributes.stream().noneMatch(each -> each.getType() == DataType.INTEGER)); + Assertions.assertEquals("testNamespace", createSchemaRequest.getNamespace()); + Assertions.assertEquals("testSchema", createSchemaRequest.getSchemaName()); + Assertions.assertSame(SchemaValidationType.MATCHING, createSchemaRequest.getValidationType()); + Assertions.assertSame(SchemaType.JSON, createSchemaRequest.getSchemaType()); + + final var updateSchemaRequest = ResourceHelper.getResource( + "schema/updateSchemaRequest.json", + UpdateSchemaRequest.class + ); + Assertions.assertNotNull(updateSchemaRequest); + schemaAttributes = updateSchemaRequest.getAttributes(); + Assertions.assertNotNull(schemaAttributes); + Assertions.assertTrue(schemaAttributes.stream().anyMatch(each -> each.getType() == DataType.ARRAY)); + Assertions.assertTrue(schemaAttributes.stream().anyMatch(each -> each.getType() == DataType.ENUM)); + Assertions.assertTrue(schemaAttributes.stream().noneMatch(each -> each.getType() == DataType.INTEGER)); + Assertions.assertEquals("testNamespace", updateSchemaRequest.getNamespace()); + Assertions.assertEquals("testSchema", updateSchemaRequest.getSchemaName()); + Assertions.assertSame(SchemaValidationType.STRICT, updateSchemaRequest.getValidationType()); + Assertions.assertSame(SchemaType.JSON, updateSchemaRequest.getSchemaType()); + + final var schemaKey = ResourceHelper.getResource( + "schema/schemaKey.json", + SchemaKey.class + ); + Assertions.assertNotNull(schemaKey); + Assertions.assertEquals("testNamespace", schemaKey.getNamespace()); + Assertions.assertEquals("testSchema", schemaKey.getSchemaName()); + Assertions.assertEquals("V1234", schemaKey.getVersion()); + } +} diff --git a/leia-models/src/test/resources/attributes/attribute.json b/leia-models/src/test/resources/attributes/attribute.json new file mode 100644 index 0000000..438939c --- /dev/null +++ b/leia-models/src/test/resources/attributes/attribute.json @@ -0,0 +1,5 @@ +{ + "type": "ARRAY", + "name": "testAttribute", + "optional": true +} \ No newline at end of file diff --git a/leia-models/src/test/resources/attributes/attributeWithQualifier.json b/leia-models/src/test/resources/attributes/attributeWithQualifier.json new file mode 100644 index 0000000..02f792c --- /dev/null +++ b/leia-models/src/test/resources/attributes/attributeWithQualifier.json @@ -0,0 +1,8 @@ +{ + "type": "ARRAY", + "name": "testAttribute", + "optional": true, + "qualifierInfo": { + "type": "PII" + } +} \ No newline at end of file diff --git a/leia-models/src/test/resources/attributes/enumAttribute.json b/leia-models/src/test/resources/attributes/enumAttribute.json new file mode 100644 index 0000000..2b9e6ce --- /dev/null +++ b/leia-models/src/test/resources/attributes/enumAttribute.json @@ -0,0 +1,11 @@ +{ + "type": "ENUM", + "name": "testAttribute", + "optional": true, + "values": [ + "TEST_ENUM" + ], + "qualifierInfo": { + "type": "PII" + } +} \ No newline at end of file diff --git a/leia-models/src/test/resources/qualifiers/piiQualifier.json b/leia-models/src/test/resources/qualifiers/piiQualifier.json new file mode 100644 index 0000000..71c5875 --- /dev/null +++ b/leia-models/src/test/resources/qualifiers/piiQualifier.json @@ -0,0 +1,3 @@ +{ + "type": "PII" +} \ No newline at end of file diff --git a/leia-models/src/test/resources/request/namespaceRequest.json b/leia-models/src/test/resources/request/namespaceRequest.json new file mode 100644 index 0000000..50467d2 --- /dev/null +++ b/leia-models/src/test/resources/request/namespaceRequest.json @@ -0,0 +1,5 @@ +{ + "namespaces": [ + "test" + ] +} \ No newline at end of file diff --git a/leia-models/src/test/resources/schema/createSchemaRequest.json b/leia-models/src/test/resources/schema/createSchemaRequest.json new file mode 100644 index 0000000..9b473a1 --- /dev/null +++ b/leia-models/src/test/resources/schema/createSchemaRequest.json @@ -0,0 +1,15 @@ +{ + "namespace": "testNamespace", + "schemaName": "testSchema", + "schemaType": "JSON", + "attributes": [ + { + "type": "ARRAY", + "name": "testAttribute", + "optional": true, + "qualifierInfo": { + "type": "PII" + } + } + ] +} \ No newline at end of file diff --git a/leia-models/src/test/resources/schema/schemaDetails.json b/leia-models/src/test/resources/schema/schemaDetails.json new file mode 100644 index 0000000..8c20ab9 --- /dev/null +++ b/leia-models/src/test/resources/schema/schemaDetails.json @@ -0,0 +1,33 @@ +{ + "schemaKey": { + "namespace": "testNamespace", + "schemaName": "testSchema", + "version": "V1234" + }, + "schemaState": "CREATED", + "schemaType": "JSON", + "schemaMeta": { + "createdBy": "testUser" + }, + "attributes": [ + { + "type": "ARRAY", + "name": "testAttribute", + "optional": true, + "qualifierInfo": { + "type": "PII" + } + }, + { + "type": "ENUM", + "name": "testAttribute", + "optional": true, + "values": [ + "TEST_ENUM" + ], + "qualifierInfo": { + "type": "PII" + } + } + ] +} \ No newline at end of file diff --git a/leia-models/src/test/resources/schema/schemaKey.json b/leia-models/src/test/resources/schema/schemaKey.json new file mode 100644 index 0000000..9791ffc --- /dev/null +++ b/leia-models/src/test/resources/schema/schemaKey.json @@ -0,0 +1,5 @@ +{ + "namespace": "testNamespace", + "schemaName": "testSchema", + "version": "V1234" +} \ No newline at end of file diff --git a/leia-models/src/test/resources/schema/updateSchemaRequest.json b/leia-models/src/test/resources/schema/updateSchemaRequest.json new file mode 100644 index 0000000..570bdd4 --- /dev/null +++ b/leia-models/src/test/resources/schema/updateSchemaRequest.json @@ -0,0 +1,28 @@ +{ + "namespace": "testNamespace", + "schemaName": "testSchema", + "version": "V1234", + "validationType": "STRICT", + "schemaType": "JSON", + "attributes": [ + { + "type": "ARRAY", + "name": "testAttribute", + "optional": true, + "qualifierInfo": { + "type": "PII" + } + }, + { + "type": "ENUM", + "name": "testAttribute", + "optional": true, + "values": [ + "TEST_ENUM" + ], + "qualifierInfo": { + "type": "PII" + } + } + ] +} \ No newline at end of file diff --git a/leia-parent/pom.xml b/leia-parent/pom.xml index 7c46c22..dbef43b 100644 --- a/leia-parent/pom.xml +++ b/leia-parent/pom.xml @@ -115,6 +115,24 @@ org.aspectj ${aspectjrt.version} + + mockito-core + org.mockito + test + ${mockito.version} + + + mockito-junit-jupiter + org.mockito + test + ${mockito.version} + + + mockito-inline + org.mockito + test + ${mockito.version} + @@ -157,22 +175,4 @@ ${guava-retrying.version} - - - - - add-java-open-options-for-jdk16+ - - [16,) - - - - --add-opens java.base/java.net=ALL-UNNAMED - --add-opens java.base/sun.net=ALL-UNNAMED - - - - - \ No newline at end of file diff --git a/leia-repository/src/main/java/com/grookage/leia/repository/SchemaRepository.java b/leia-repository/src/main/java/com/grookage/leia/repository/SchemaRepository.java index ba731cd..36a1dd8 100644 --- a/leia-repository/src/main/java/com/grookage/leia/repository/SchemaRepository.java +++ b/leia-repository/src/main/java/com/grookage/leia/repository/SchemaRepository.java @@ -19,25 +19,22 @@ import com.grookage.leia.models.schema.SchemaDetails; import com.grookage.leia.models.schema.SchemaKey; import com.grookage.leia.models.schema.engine.SchemaState; -import com.grookage.leia.models.storage.StoredSchema; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.function.Function; public interface SchemaRepository { - List get(final String namespace, final String schemaName); + List get(final String namespace, final String schemaName); - void create(final StoredSchema schema); + void create(final SchemaDetails schema); - void update(final StoredSchema schema); + void update(final SchemaDetails schema); - Optional get(final SchemaKey schemaKey); + Optional get(final SchemaKey schemaKey); List getSchemas(final Set namespaces, - final Set schemaStates, - final Function mutator); + final Set schemaStates); } diff --git a/pom.xml b/pom.xml index 04795b4..fa1c744 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ Leia https://github.com/grookage/leia - Chaos-Monkey for dropwizard + Schema Registry 2024 @@ -42,17 +42,16 @@ - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + - scm:git:https://github.com/grookage/leia.git scm:git:https://github.com/grookage/leia.git @@ -93,6 +92,11 @@ 3.2.1 3.6.3 1.6 + + + **com/grookage/leia/** + + https://sonarcloud.io @@ -149,6 +153,7 @@ org.apache.maven.plugins ${maven.source.plugin.version} + maven-javadoc-plugin @@ -166,10 +171,22 @@ ${maven.javadoc.plugin.version} + + org.sonatype.central + central-publishing-maven-plugin + 0.5.0 + true + + central + true + published + + + org.sonatype.plugins nexus-staging-maven-plugin - ${nexus.staging.plguin.version} + 1.7.0 true ossrh @@ -193,25 +210,37 @@ - org.apache.maven.plugins maven-gpg-plugin - ${maven.gpg.plugin.version} - sign-artifacts - verify - - sign - + gpg true - gpg2 + + sign + + sign-artifacts + verify + org.apache.maven.plugins + ${maven.gpg.plugin.version} + + add-java-open-options-for-jdk16+ + + [16,) + + + + --add-opens java.base/java.net=ALL-UNNAMED + --add-opens java.base/sun.net=ALL-UNNAMED + + +