From 88f749277195998d150925e14e12021cc2e9292b Mon Sep 17 00:00:00 2001 From: Dan Timoney Date: Wed, 11 Mar 2020 15:54:10 -0400 Subject: Add data persistence Add code to persist MD-SAL data (test-results) Change-Id: I2c6d3e94e9e46ccbfad479c6d89507ec37939496 Issue-ID: CCSDK-2096 Signed-off-by: Dan Timoney --- .../onap/ccsdk/sli/core/sliapi/springboot/App.java | 5 + .../controllers/data/TestResultConfig.java | 50 ++++++ .../controllers/data/TestResultOperational.java | 51 ++++++ .../data/TestResultsConfigRepository.java | 12 ++ .../data/TestResultsOperationalRepository.java | 12 ++ .../controllers/swagger/RestconfApiController.java | 191 +++++++++++++++++++-- .../sliapi/springboot/core/ServletFilters.java | 4 +- .../sli/core/sliapi/springboot/core/WebConfig.java | 49 +++++- .../src/main/resources/application.properties | 2 +- .../springboot/RestconfApiControllerTest.java | 28 +++ 10 files changed, 388 insertions(+), 16 deletions(-) create mode 100644 sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultConfig.java create mode 100644 sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultOperational.java create mode 100644 sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsConfigRepository.java create mode 100644 sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsOperationalRepository.java diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/App.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/App.java index 67f54914..ed3ee044 100644 --- a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/App.java +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/App.java @@ -22,8 +22,13 @@ package org.onap.ccsdk.sli.core.sliapi.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import springfox.documentation.swagger2.annotations.EnableSwagger2; @SpringBootApplication +@EnableSwagger2 +@ComponentScan(basePackages = { "org.onap.ccsdk.sli.core.sliapi.springboot.*" }) + public class App { public static void main(String[] args) throws Exception { diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultConfig.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultConfig.java new file mode 100644 index 00000000..f8ed1b4c --- /dev/null +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultConfig.java @@ -0,0 +1,50 @@ +package org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +@Entity +public class TestResultConfig { + + + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private Long id; + + private String testIdentifier; + private String results; + + public TestResultConfig() + { + + } + public TestResultConfig(String testIdentifier, String results) { + this.testIdentifier = testIdentifier; + this.results = results; + } + + public String getTestIdentifier() { + return testIdentifier; + } + + public void setTestIdentifier(String testIdentifier) { + this.testIdentifier = testIdentifier; + } + + public String getResults() { + return results; + } + + public void setResults(String results) { + this.results = results; + } + + + + +} diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultOperational.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultOperational.java new file mode 100644 index 00000000..4c3709e6 --- /dev/null +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultOperational.java @@ -0,0 +1,51 @@ +package org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +@Entity +public class TestResultOperational { + + + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private Long id; + + private String testIdentifier; + private String results; + + public TestResultOperational() + { + + } + + public TestResultOperational(String testIdentifier, String results) { + this.testIdentifier = testIdentifier; + this.results = results; + } + + public String getTestIdentifier() { + return testIdentifier; + } + + public void setTestIdentifier(String testIdentifier) { + this.testIdentifier = testIdentifier; + } + + public String getResults() { + return results; + } + + public void setResults(String results) { + this.results = results; + } + + + + +} diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsConfigRepository.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsConfigRepository.java new file mode 100644 index 00000000..1a73b3f5 --- /dev/null +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsConfigRepository.java @@ -0,0 +1,12 @@ +package org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data; + +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + +public interface TestResultsConfigRepository extends CrudRepository { + + List findByTestIdentifier(String testIdentifier); + + +} diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsOperationalRepository.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsOperationalRepository.java new file mode 100644 index 00000000..d81c02b2 --- /dev/null +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/data/TestResultsOperationalRepository.java @@ -0,0 +1,12 @@ +package org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data; + +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + +public interface TestResultsOperationalRepository extends CrudRepository { + + List findByTestIdentifier(String testIdentifier); + + +} diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/swagger/RestconfApiController.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/swagger/RestconfApiController.java index 2972cd79..aa9a9d7e 100644 --- a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/swagger/RestconfApiController.java +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/controllers/swagger/RestconfApiController.java @@ -20,38 +20,53 @@ package org.onap.ccsdk.sli.core.sliapi.springboot.controllers.swagger; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import org.onap.ccsdk.sli.core.sli.SvcLogicContext; import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase; import org.onap.ccsdk.sli.core.sliapi.model.ExecuteGraphInput; import org.onap.ccsdk.sli.core.sliapi.model.ResponseFields; -import org.onap.ccsdk.sli.core.sliapi.springboot.controllers.swagger.RestconfApi; +import org.onap.ccsdk.sli.core.sliapi.model.TestResult; +import org.onap.ccsdk.sli.core.sliapi.model.TestResults; +import org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data.TestResultConfig; +import org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data.TestResultsConfigRepository; +import org.onap.ccsdk.sli.core.sliapi.springboot.controllers.data.TestResultsOperationalRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import com.google.gson.JsonObject; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.*; @javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2020-02-20T12:50:11.207-05:00") @Controller +@ComponentScan(basePackages = {"org.onap.ccsdk.sli.core.sliapi.springboot.*"}) +@EntityScan("org.onap.ccsdk.sli.core.sliapi.springboot.*") public class RestconfApiController implements RestconfApi { private final ObjectMapper objectMapper; private final HttpServletRequest request; - @Autowired - protected SvcLogicServiceBase svc; + @Autowired + protected SvcLogicServiceBase svc; + + @Autowired + private TestResultsConfigRepository testResultsConfigRepository; + + @Autowired + private TestResultsOperationalRepository testResultsOperationalRepository; + private static final Logger log = LoggerFactory.getLogger(RestconfApiController.class); @org.springframework.beans.factory.annotation.Autowired @@ -175,6 +190,158 @@ public class RestconfApiController implements RestconfApi { } } + @Override + public ResponseEntity deleteTestResult(String testIdentifier) { + + List testResultConfigs = testResultsConfigRepository.findByTestIdentifier(testIdentifier); + + if (testResultConfigs != null) { + Iterator testResultConfigIterator = testResultConfigs.iterator(); + while (testResultConfigIterator.hasNext()) { + testResultsConfigRepository.delete(testResultConfigIterator.next()); + } + } + + return (new ResponseEntity<>(HttpStatus.OK)); + } + + @Override + public ResponseEntity deleteTestResults() { + + testResultsConfigRepository.deleteAll(); + + return (new ResponseEntity<>(HttpStatus.OK)); + } + + @Override + public ResponseEntity gETTestResults() { + + TestResults results = new TestResults(); + + testResultsOperationalRepository.findAll().forEach(testResult -> { + TestResult item = null; + try { + item = objectMapper.readValue(testResult.getResults(), TestResult.class); + results.addTestResultsItem(item); + } catch (JsonProcessingException e) { + log.error("Could not convert testResult", e); + } + }); + + + return new ResponseEntity<>(results, HttpStatus.OK); + } + + @Override + public ResponseEntity getTestResult(String testIdentifier) { + List testResultConfigs = testResultsConfigRepository.findByTestIdentifier(testIdentifier); + + if ((testResultConfigs == null) || (testResultConfigs.size() == 0)) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } else { + TestResultConfig testResultConfig = testResultConfigs.get(0); + TestResult testResult = null; + try { + testResult = objectMapper.readValue(testResultConfig.getResults(), TestResult.class); + } catch (JsonProcessingException e) { + log.error("Cannot convert test result", e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + + return new ResponseEntity<>(testResult, HttpStatus.OK); + } + } + + @Override + public ResponseEntity getTestResults() { + if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) { + } else { + log.warn("ObjectMapper or HttpServletRequest not configured in default RestconfApi interface so no example is generated"); + } + + TestResults results = new TestResults(); + + testResultsConfigRepository.findAll().forEach(testResult -> { + TestResult item = null; + try { + item = objectMapper.readValue(testResult.getResults(), TestResult.class); + results.addTestResultsItem(item); + } catch (JsonProcessingException e) { + log.error("Could not convert testResult", e); + } + }); + + + return new ResponseEntity<>(results, HttpStatus.OK); + } + + @Override + public ResponseEntity pUTTestResult(String testIdentifier, @Valid TestResult testResult) { + if(getObjectMapper().isPresent() && getAcceptHeader().isPresent()) { + } else { + log.warn("ObjectMapper or HttpServletRequest not configured in default RestconfApi interface so no example is generated"); + } + + List testResultConfigs = testResultsConfigRepository.findByTestIdentifier(testIdentifier); + Iterator testResultIter = testResultConfigs.iterator(); + while (testResultIter.hasNext()) { + testResultsConfigRepository.delete(testResultIter.next()); + } + + TestResultConfig testResultConfig = null; + try { + testResultConfig = new TestResultConfig(testResult.getTestIdentifier(), objectMapper.writeValueAsString(testResult)); + testResultsConfigRepository.save(testResultConfig); + } catch (JsonProcessingException e) { + log.error("Could not save test result", e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + return new ResponseEntity<>(testResult, HttpStatus.OK); + } + + @Override + public ResponseEntity postTestResults(@Valid TestResults testResults) { + List resultList = testResults.getTestResults(); + + Iterator resultIterator = resultList.iterator(); + + while (resultIterator.hasNext()) { + TestResult curResult = resultIterator.next(); + try { + testResultsConfigRepository.save(new TestResultConfig(curResult.getTestIdentifier(), objectMapper.writeValueAsString(curResult))); + } catch (JsonProcessingException e) { + log.error("Could not save test result", e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + return new ResponseEntity<>(testResults, HttpStatus.OK); + } + + @Override + public ResponseEntity putTestResults(@Valid TestResults testResults) { + testResultsConfigRepository.deleteAll(); + + List resultList = testResults.getTestResults(); + + Iterator resultIterator = resultList.iterator(); + + + while (resultIterator.hasNext()) { + TestResult curResult = resultIterator.next(); + try { + testResultsConfigRepository.save(new TestResultConfig(curResult.getTestIdentifier(), objectMapper.writeValueAsString(curResult))); + } catch (JsonProcessingException e) { + log.error("Could not save test result", e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + return new ResponseEntity<>(testResults, HttpStatus.OK); + } + public static String propsToJson(Properties props, String root) { StringBuffer sbuff = new StringBuffer(); diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/ServletFilters.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/ServletFilters.java index c56cf3bf..bfec1c93 100644 --- a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/ServletFilters.java +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/ServletFilters.java @@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration; @Configuration public class ServletFilters { - @Bean +/* @Bean public FilterRegistrationBean payloadFilterRegistration() throws ServletException { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new PayloadLoggingServletFilter()); @@ -38,5 +38,5 @@ public class ServletFilters { registration.setName("payloadFilter"); registration.setOrder(0); return registration; - } + }*/ } \ No newline at end of file diff --git a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/WebConfig.java b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/WebConfig.java index fb4fe085..41d3791b 100644 --- a/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/WebConfig.java +++ b/sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/core/WebConfig.java @@ -21,23 +21,70 @@ package org.onap.ccsdk.sli.core.sliapi.springboot.core; import org.onap.logging.filter.spring.LoggingInterceptor; +import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + @EnableWebMvc @Configuration +@EnableJpaRepositories("org.onap.ccsdk.sli.core.sliapi.springboot.*") +@ComponentScan(basePackages = {"org.onap.ccsdk.sli.core.sliapi.springboot.*"}) +@EntityScan("org.onap.ccsdk.sli.core.sliapi.springboot.*") +@EnableTransactionManagement public class WebConfig implements WebMvcConfigurer { - @Bean +/* @Bean LoggingInterceptor loggingInterceptor() { return new LoggingInterceptor(); } public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loggingInterceptor()); // handles audit log entries + }*/ + + @Bean + public DataSource dataSource() { + + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); + builder.setName("sdnctl"); + return builder.setType(EmbeddedDatabaseType.DERBY).build(); + } + + @Bean + public EntityManagerFactory entityManagerFactory() { + + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setGenerateDdl(true); + + LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); + factory.setJpaVendorAdapter(vendorAdapter); + factory.setPackagesToScan("org.onap.ccsdk.sli.core.sliapi.springboot.*"); + factory.setDataSource(dataSource()); + factory.afterPropertiesSet(); + + return factory.getObject(); } + @Bean + public PlatformTransactionManager transactionManager() { + + JpaTransactionManager txManager = new JpaTransactionManager(); + txManager.setEntityManagerFactory(entityManagerFactory()); + return txManager; + } } \ No newline at end of file diff --git a/sliapi/springboot/src/main/resources/application.properties b/sliapi/springboot/src/main/resources/application.properties index 851488b9..6a4acc7e 100644 --- a/sliapi/springboot/src/main/resources/application.properties +++ b/sliapi/springboot/src/main/resources/application.properties @@ -3,7 +3,7 @@ server.contextPath=/restconf server.port=8080 spring.jackson.date-format=org.onap.ccsdk.sli.core.sliapi.springboot.controllers.swagger.RFC3339DateFormat spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false -spring.datasource.url=jdbc:derby:sdnctl;create=true +spring.datasource.url=jdbc:derby:memory:datasource spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.DerbyTenSevenDialect spring.jpa.hibernate.ddl-auto=update logging.level.com.att=TRACE diff --git a/sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java b/sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java index a61a470e..b4c62909 100644 --- a/sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java +++ b/sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java @@ -118,6 +118,34 @@ public class RestconfApiControllerTest { } + @Test + public void testTestResultAdd() throws Exception { + String url = "/restconf/config/SLI-API:test-results"; + + MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(url)).andReturn(); + + assertEquals(200, mvcResult.getResponse().getStatus()); + + String jsonString = "{\n" + + " \"test-results\" : [\n" + + " {\n" + + " \"test-identifier\" : \"test-1\",\n" + + " \"results\" : [\"test result 1\"]\n" + + " }\n" + + " ]\n" + + "}"; + + mvcResult = mvc.perform(MockMvcRequestBuilders.post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content(jsonString)) + .andReturn(); + + assertEquals(200, mvcResult.getResponse().getStatus()); + + mvcResult = mvc.perform(MockMvcRequestBuilders.get(url)).andReturn(); + + assertEquals(200, mvcResult.getResponse().getStatus()); + assertEquals(jsonString.replaceAll("\\s+",""), mvcResult.getResponse().getContentAsString().replaceAll("\\s+","")); + } + private String mapToJson(Object obj) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.writeValueAsString(obj); -- cgit 1.2.3-korg