diff options
author | Fiete Ostkamp <fiete.ostkamp@telekom.de> | 2024-11-22 13:49:38 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2024-11-22 13:49:38 +0000 |
commit | 266d4ba4f01ac7d451e0b62fd24a381fa75265a7 (patch) | |
tree | bca86c88cb317ecc7503c0dc044578b077e214bd | |
parent | 101f84b82fee1e1e245fb64df9269b9ebf5fd22d (diff) | |
parent | f63000bb493505f5660ecd000e688013c1fbe7ec (diff) |
Merge "RestApi for DB Schema Initialization-Address Review comments"
6 files changed, 366 insertions, 2 deletions
diff --git a/src/main/java/org/onap/aai/rest/SchemaJobStatusController.java b/src/main/java/org/onap/aai/rest/SchemaJobStatusController.java new file mode 100644 index 0000000..50cbddb --- /dev/null +++ b/src/main/java/org/onap/aai/rest/SchemaJobStatusController.java @@ -0,0 +1,54 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.service.SchemaJobStatusService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; + + +@RestController +@RequiredArgsConstructor +public class SchemaJobStatusController { + + private static final Logger LOGGER = LoggerFactory.getLogger(SchemaJobStatusController.class); + + private final SchemaJobStatusService schemaJobStatusService; + + @GetMapping("/isSchemaInitialized") + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + public boolean isSchemaInitialized() throws AAIException { + + LOGGER.info("Checking if schema is initialized."); + return schemaJobStatusService.isSchemaInitialized(); + } + + +}
\ No newline at end of file diff --git a/src/main/java/org/onap/aai/schema/GenTester.java b/src/main/java/org/onap/aai/schema/GenTester.java index 6674610..afcd99f 100644 --- a/src/main/java/org/onap/aai/schema/GenTester.java +++ b/src/main/java/org/onap/aai/schema/GenTester.java @@ -47,6 +47,8 @@ public class GenTester { private static Logger LOGGER; private static boolean historyEnabled; + private static boolean isSchemaInitialized; + private static final String SCHEMA_INITIALIZED = "schema-initialized"; /** * The main method. @@ -113,7 +115,8 @@ public class GenTester { } else if ("GEN_DB_WITH_NO_DEFAULT_CR".equals(args[0])) { addDefaultCR = false; } else { - ErrorLogHelper.logError("AAI_3000", "Unrecognized argument passed to GenTester.java: [" + args[0] + "]. "); + ErrorLogHelper.logError("AAI_3000", + "Unrecognized argument passed to GenTester.java: [" + args[0] + "]. "); String emsg = "Unrecognized argument passed to GenTester.java: [" + args[0] + "]. "; System.out.println(emsg); @@ -138,6 +141,18 @@ public class GenTester { return; } + isSchemaInitialized = graph.traversal().V().has(SCHEMA_INITIALIZED).hasNext(); + + if (isSchemaInitialized) { + // Setting property schema-initialized to false as vertex is already there + LOGGER.debug("-- Adding a vertex with property schema-initialized as false"); + graph.traversal().V().has(SCHEMA_INITIALIZED).property(SCHEMA_INITIALIZED, "false"); + } else { + // Adding a new vertex with property schema-initialized to false + LOGGER.debug("-- Adding a vertex with property schema-initialized as false"); + graph.addVertex(SCHEMA_INITIALIZED, "false"); + } + GraphAdminDBUtils.logConfigs(graph.configuration()); LOGGER.debug("-- Loading new schema elements into JanusGraph --"); @@ -158,6 +173,13 @@ public class GenTester { LOGGER.info("Nothing to reindex."); } } + + // Setting property schema-initialized to true + LOGGER.debug("-- Updating vertex with property schema-initialized as true "); + graph.traversal().V().has(SCHEMA_INITIALIZED).property(SCHEMA_INITIALIZED, "true"); + LOGGER.debug("-- committing transaction "); + graph.tx().commit(); + graph.close(); LOGGER.info("Closed the graph"); @@ -194,7 +216,8 @@ public class GenTester { LOGGER.info("Number of open instances: {}", instances.size()); LOGGER.info("Currently open instances: [{}]", instances); instances.stream() - .filter(instance -> !instance.contains("graphadmin")) // Potentially comment this out, should there be issues with the schema creation job + .filter(instance -> !instance.contains("graphadmin")) // Potentially comment this out, should there be + // issues with the schema creation job .filter(instance -> !instance.contains("(current)")) .forEach(instance -> { LOGGER.debug("Closing open JanusGraph instance [{}] before reindexing procedure", instance); diff --git a/src/main/java/org/onap/aai/service/SchemaJobStatusService.java b/src/main/java/org/onap/aai/service/SchemaJobStatusService.java new file mode 100644 index 0000000..53e3773 --- /dev/null +++ b/src/main/java/org/onap/aai/service/SchemaJobStatusService.java @@ -0,0 +1,52 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.service; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.janusgraph.core.JanusGraph; +import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.logging.ErrorLogHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class SchemaJobStatusService { + private static final Logger LOGGER = LoggerFactory.getLogger(SchemaJobStatusService.class); + private final JanusGraph graph = AAIGraph.getInstance().getGraph(); ; + + public boolean isSchemaInitialized() throws AAIException { + if (graph == null) { + ErrorLogHelper.logError("AAI_5102", "Error creating JanusGraph graph."); + throw new AAIException("AAI_5102", "Graph instance is null."); + } + LOGGER.debug("Successfully loaded a JanusGraph graph."); + + GraphTraversalSource g = graph.traversal(); + try { + // Check if there is a vertex with the property "schema-initialized" set to "true" + return g.V().has("schema-initialized", "true").hasNext(); + } catch (Exception e) { + LOGGER.error("Error during schema initialization check", e); + throw new AAIException("Error checking schema initialization: " + e.getMessage(), e); + } + } +} diff --git a/src/test/java/org/onap/aai/config/WebClientConfiguration.java b/src/test/java/org/onap/aai/config/WebClientConfiguration.java index c76b9b1..8f395ed 100644 --- a/src/test/java/org/onap/aai/config/WebClientConfiguration.java +++ b/src/test/java/org/onap/aai/config/WebClientConfiguration.java @@ -48,4 +48,17 @@ public class WebClientConfiguration { }) .build(); } + + @Lazy + @Bean + @Primary + WebTestClient appClient(@Value("${server.port}") int port) { + return WebTestClient.bindToServer() + .baseUrl("http://localhost:" + port) + .responseTimeout(Duration.ofSeconds(300)) + .defaultHeaders(headers -> { + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + }) + .build(); + } } diff --git a/src/test/java/org/onap/aai/rest/SchemaJobStatusControllerTest.java b/src/test/java/org/onap/aai/rest/SchemaJobStatusControllerTest.java new file mode 100644 index 0000000..971a174 --- /dev/null +++ b/src/test/java/org/onap/aai/rest/SchemaJobStatusControllerTest.java @@ -0,0 +1,90 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest; + +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.aai.config.WebClientConfiguration; +import org.onap.aai.restclient.PropertyPasswordConfiguration; +import org.onap.aai.service.SchemaJobStatusService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.reactive.server.WebTestClient; + + +@Import(WebClientConfiguration.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@ContextConfiguration(initializers = PropertyPasswordConfiguration.class) +public class SchemaJobStatusControllerTest { + + @MockBean + private SchemaJobStatusService schemaJobStatusService; + + @Autowired + private SchemaJobStatusController schemaJobStatusController; + + @Autowired + WebTestClient webClient; + + @BeforeEach + void setUp() { + // Bind the WebTestClient to the controller + webClient = WebTestClient.bindToController(schemaJobStatusController).build(); + } + + @Test + void testIsSchemaInitializedTrue() throws Exception { + when(schemaJobStatusService.isSchemaInitialized()).thenReturn(true); + + webClient.get() + .uri("/isSchemaInitialized") + .exchange() + .expectStatus() + .isOk() + .expectBody(Boolean.class).isEqualTo(true); + } + + @Test + void testIsSchemaInitializedFalse() throws Exception { + when(schemaJobStatusService.isSchemaInitialized()).thenReturn(false); + + webClient.get() + .uri("/isSchemaInitialized") + .exchange() + .expectStatus() + .isOk() + .expectBody(Boolean.class).isEqualTo(false); + } + + @Test + void testInvalidEndpoint() { + webClient.get() + .uri("/nonexistentEndpoint") + .exchange() + .expectStatus() + .isNotFound(); + } +}
\ No newline at end of file diff --git a/src/test/java/org/onap/aai/rest/SchemaJobStatusServiceTest.java b/src/test/java/org/onap/aai/rest/SchemaJobStatusServiceTest.java new file mode 100644 index 0000000..108e0eb --- /dev/null +++ b/src/test/java/org/onap/aai/rest/SchemaJobStatusServiceTest.java @@ -0,0 +1,132 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2024 Deutsche Telekom. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.rest; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.janusgraph.core.JanusGraphTransaction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.onap.aai.AAISetup; +import org.onap.aai.dbmap.AAIGraph; +import org.onap.aai.exceptions.AAIException; +import org.onap.aai.service.SchemaJobStatusService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(classes = SchemaJobStatusService.class) +public class SchemaJobStatusServiceTest extends AAISetup { + + private static final Logger logger = LoggerFactory.getLogger(SchemaJobStatusServiceTest.class); + + @Autowired + private SchemaJobStatusService schemaJobStatusService; + + private void createGraph(boolean initialized) { + JanusGraphTransaction transaction = AAIGraph.getInstance().getGraph().newTransaction(); + boolean success = true; + try { + GraphTraversalSource g = transaction.traversal(); + g.addV().property("schema-initialized", initialized) + .next(); + + } catch(Exception ex){ + success = false; + logger.error("Unable to create the vertexes", ex); + } finally { + if(success){ + transaction.commit(); + } else { + transaction.rollback(); + fail("Unable to setup the graph"); + } + } + } + + private void createGraphWithoutSchemaVertex() { + JanusGraphTransaction transaction = AAIGraph.getInstance().getGraph().newTransaction(); + boolean success = true; + try { + GraphTraversalSource g = transaction.traversal(); + + g.addV().property("aai-node-type", "pserver") + .next(); + + } catch(Exception ex){ + success = false; + logger.error("Unable to create the vertexes", ex); + } finally { + if(success){ + transaction.commit(); + } else { + transaction.rollback(); + fail("Unable to setup the graph"); + } + } + } + + @Test + public void testSchemaInitializedTrue() throws AAIException{ + createGraph(true); + boolean result = schemaJobStatusService.isSchemaInitialized(); + assertTrue(result); + } + + @Test + public void testSchemaInitializedFalse() throws AAIException{ + createGraph(false); + boolean result = schemaJobStatusService.isSchemaInitialized(); + assertFalse(result); + } + + @Test + public void testVertexNotPresent() throws AAIException{ + createGraphWithoutSchemaVertex(); + boolean result = schemaJobStatusService.isSchemaInitialized(); + assertFalse(result); + } + + @AfterEach + public void tearDown(){ + JanusGraphTransaction transaction = AAIGraph.getInstance().getGraph().newTransaction(); + boolean success = true; + try { + GraphTraversalSource g = transaction.traversal(); + g.V().has("schema-initialized") + .toList() + .forEach(v -> v.remove()); + } catch(Exception ex){ + success = false; + logger.error("Unable to remove the vertexes", ex); + } finally { + if(success){ + transaction.commit(); + } else { + transaction.rollback(); + fail("Unable to teardown the graph"); + } + } + } +} |