From c0b9d01cbc3a3d3b1ce32178394e8fd74a10de65 Mon Sep 17 00:00:00 2001 From: Lathish Date: Fri, 26 Apr 2019 08:46:13 +0000 Subject: VNFM simulator implementation for instantiate flow Issue-ID: SO-1773 Change-Id: I710fe6905d650df29f7550f4eafde2f672301bc4 Signed-off-by: Lathish --- .../svnfm/simulator/config/ApplicationConfig.java | 43 +++ .../svnfm/simulator/config/SvnfmApplication.java | 6 +- .../simulator/config/WebSecurityConfigImpl.java | 48 ++++ .../onap/svnfm/simulator/constants/Constant.java | 8 +- .../simulator/controller/SvnfmController.java | 121 +++++---- .../org/onap/svnfm/simulator/model/VnfJob.java | 73 ----- .../onap/svnfm/simulator/model/VnfOperation.java | 80 ++++++ .../java/org/onap/svnfm/simulator/model/Vnfds.java | 97 +++++++ .../simulator/repository/VnfJobRepository.java | 33 --- .../repository/VnfOperationRepository.java | 33 +++ .../simulator/repository/VnfmCacheRepository.java | 31 ++- .../simulator/services/OperationProgressor.java | 296 +++++++++++++++++++++ .../simulator/services/SubscriptionService.java | 21 ++ .../svnfm/simulator/services/SvnfmService.java | 148 ++++++----- .../onap/svnfm/simulator/services/VnfmHelper.java | 39 ++- .../src/main/resources/application.properties | 13 - .../src/main/resources/application.yaml | 59 ++++ .../simulator/controllers/TestSvnfmController.java | 17 +- 18 files changed, 906 insertions(+), 260 deletions(-) create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/WebSecurityConfigImpl.java delete mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfJob.java create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfOperation.java create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/Vnfds.java delete mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfJobRepository.java create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfOperationRepository.java create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java create mode 100644 vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SubscriptionService.java delete mode 100644 vnfm-simulator/vnfm-service/src/main/resources/application.properties create mode 100644 vnfm-simulator/vnfm-service/src/main/resources/application.yaml (limited to 'vnfm-simulator/vnfm-service/src') diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java new file mode 100644 index 0000000000..91b79754a5 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/ApplicationConfig.java @@ -0,0 +1,43 @@ +package org.onap.svnfm.simulator.config; + +import java.net.InetAddress; +import java.util.Arrays; +import org.onap.svnfm.simulator.constants.Constant; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +@Component +public class ApplicationConfig implements ApplicationRunner { + + private static final String PORT = "local.server.port"; + + @Autowired + private Environment environment; + + private String baseUrl; + + @Override + public void run(final ApplicationArguments args) throws Exception { + baseUrl = "http://" + InetAddress.getLocalHost().getHostAddress() + ":" + environment.getProperty(PORT); + } + + public String getBaseUrl() { + return baseUrl; + } + + @Bean + public CacheManager cacheManager() { + Cache inlineResponse201 = new ConcurrentMapCache(Constant.IN_LINE_RESPONSE_201_CACHE); + SimpleCacheManager manager = new SimpleCacheManager(); + manager.setCaches(Arrays.asList(inlineResponse201)); + return manager; + } +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/SvnfmApplication.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/SvnfmApplication.java index 84b45d0bac..723ae906e6 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/SvnfmApplication.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/SvnfmApplication.java @@ -20,6 +20,7 @@ package org.onap.svnfm.simulator.config; +import org.onap.svnfm.simulator.controller.SvnfmController; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; @@ -27,7 +28,10 @@ import org.springframework.cache.annotation.EnableCaching; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; /** - * + * The spring boot application for the VNF LCM. + *

+ * The VNFM receives requests through its REST API {@link SvnfmController} + * * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) * @author ronan.kenny@est.tech */ diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/WebSecurityConfigImpl.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/WebSecurityConfigImpl.java new file mode 100644 index 0000000000..18eadd2fc3 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/config/WebSecurityConfigImpl.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.svnfm.simulator.config; + +import org.onap.so.security.MSOSpringFirewall; +import org.onap.so.security.WebSecurityConfig; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.firewall.StrictHttpFirewall; + +/** + * Configure the web security for the application. + */ +@EnableWebSecurity +public class WebSecurityConfigImpl extends WebSecurityConfig { + + @Override + protected void configure(final HttpSecurity http) throws Exception { + http.csrf().disable().authorizeRequests().antMatchers("/**").permitAll(); + } + + @Override + public void configure(final WebSecurity web) throws Exception { + super.configure(web); + final StrictHttpFirewall firewall = new MSOSpringFirewall(); + web.httpFirewall(firewall); + } + +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/constants/Constant.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/constants/Constant.java index bd380903d5..98f47bf455 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/constants/Constant.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/constants/Constant.java @@ -27,9 +27,13 @@ package org.onap.svnfm.simulator.constants; */ public class Constant { + public static final String BASE_URL = "/vnflcm/v1"; public static final String VNF_PROVIDER = "XYZ"; - public static final String VNF_PROVIDER_NAME = "SGSN-MME"; + public static final String VNF_PROVIDER_NAME = "vCPE"; public static final String VNF_SOFTWARE_VERSION = "1.24"; - public static final String VNFD_VERSION = "onapmme01_cxp9025898_4r85d01"; + public static final String VNFD_VERSION = "onapvcpe01_cxp9025898_4r85d01"; public static final String VNF_NOT_INSTANTIATED = "NOT_INSTANTIATED"; + public static final String VNF_CONFIG_PROPERTIES = + "{\"isAutoScaleEnabled\": \"true\",\"isAutoHealingEnabled\": \"true\"}"; + public static final String IN_LINE_RESPONSE_201_CACHE = "inlineResponse201"; } diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/controller/SvnfmController.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/controller/SvnfmController.java index 11099a24fc..e6bc06374c 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/controller/SvnfmController.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/controller/SvnfmController.java @@ -22,30 +22,37 @@ package org.onap.svnfm.simulator.controller; import java.util.UUID; import javax.ws.rs.core.MediaType; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse2001; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest; +import org.onap.svnfm.simulator.constants.Constant; import org.onap.svnfm.simulator.repository.VnfmCacheRepository; import org.onap.svnfm.simulator.services.SvnfmService; -import org.onap.vnfm.v1.model.CreateVnfRequest; -import org.onap.vnfm.v1.model.InlineResponse201; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; /** - * + * * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) * @author Ronan Kenny (ronan.kenny@est.tech) */ @RestController -@RequestMapping("/svnfm") +@RequestMapping(path = Constant.BASE_URL, produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON) public class SvnfmController { @Autowired @@ -57,25 +64,30 @@ public class SvnfmController { private static final Logger LOGGER = LoggerFactory.getLogger(SvnfmController.class); /** - * - * @param createVNFRequest - * @return + * To create the Vnf and stores the response in cache + * + * @param CreateVnfRequest + * @return InlineResponse201 */ - @RequestMapping(method = RequestMethod.POST, value = "/vnf_instances") + @PostMapping(value = "/vnf_instances") public ResponseEntity createVnf(@RequestBody final CreateVnfRequest createVNFRequest) { - LOGGER.info("Start createVnf------"); + LOGGER.info("Start createVnf {}", createVNFRequest); + final String id = UUID.randomUUID().toString(); final HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", MediaType.APPLICATION_JSON); - return new ResponseEntity<>(vnfmCacheRepository.createVnf(createVNFRequest), headers, HttpStatus.CREATED); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + final ResponseEntity responseEntity = + new ResponseEntity<>(vnfmCacheRepository.createVnf(createVNFRequest, id), headers, HttpStatus.CREATED); + LOGGER.info("Finished create {}", responseEntity); + return responseEntity; } /** - * + * Get the vnf by id from cache + * * @param vnfId - * @return vnfm cache repository + * @return InlineResponse201 */ - @RequestMapping(method = RequestMethod.GET, value = "/vnf_instances/{vnfInstanceId}", - produces = MediaType.APPLICATION_JSON) + @GetMapping(value = "/vnf_instances/{vnfInstanceId}") @ResponseStatus(code = HttpStatus.OK) public InlineResponse201 getVnf(@PathVariable("vnfInstanceId") final String vnfId) { LOGGER.info("Start getVnf------"); @@ -83,42 +95,29 @@ public class SvnfmController { } /** - * + * To instantiate the vnf and returns the operation id + * * @param vnfId - * @return response entity * @throws InterruptedException */ - @RequestMapping(method = RequestMethod.POST, value = "/vnf_instances/{vnfInstanceId}/instantiate") - public ResponseEntity instantiateVnf(@PathVariable("vnfInstanceId") final String vnfId) - throws InterruptedException { - LOGGER.info("Start instantiateVNFRequest"); - final String instantiateJobId = UUID.randomUUID().toString(); - final HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", MediaType.APPLICATION_JSON); - headers.add("Location", instantiateJobId); - return new ResponseEntity<>(svnfmService.instatiateVnf(vnfId, instantiateJobId), headers, HttpStatus.ACCEPTED); - } + @PostMapping(value = "/vnf_instances/{vnfInstanceId}/instantiate") + public ResponseEntity instantiateVnf(@PathVariable("vnfInstanceId") final String vnfId, + @RequestBody final InstantiateVnfRequest instantiateVNFRequest) { + LOGGER.info("Start instantiateVNFRequest {} ", instantiateVNFRequest); - /** - * - * @param jobId - * @return response entity - * @throws InterruptedException - */ - public ResponseEntity getJobStatus(@PathVariable("jobId") final String jobId) throws InterruptedException { - LOGGER.info("Start getJobStatus"); final HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", MediaType.APPLICATION_JSON); - return new ResponseEntity<>(svnfmService.getJobStatus(jobId), headers, HttpStatus.ACCEPTED); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + headers.add(HttpHeaders.LOCATION, svnfmService.instantiateVnf(vnfId, instantiateVNFRequest)); + return new ResponseEntity<>(headers, HttpStatus.ACCEPTED); } /** - * + * To delete the vnf by id + * * @param vnfId - * @return delete VNF + * @return InlineResponse201 */ - @RequestMapping(method = RequestMethod.DELETE, value = "/vnf_instances/{vnfInstanceId}", - produces = MediaType.APPLICATION_JSON) + @DeleteMapping(value = "/vnf_instances/{vnfInstanceId}") @ResponseStatus(code = HttpStatus.OK) public InlineResponse201 deleteVnf(@PathVariable("vnfInstanceId") final String vnfId) { LOGGER.info("Start deleting Vnf------"); @@ -126,17 +125,45 @@ public class SvnfmController { } /** - * + * To terminate the vnf by id + * * @param vnfId - * @return response entity * @throws InterruptedException */ - @RequestMapping(method = RequestMethod.POST, value = "/vnf_instances/{vnfInstanceId}/terminate") - public ResponseEntity terminateVnf(@PathVariable("vnfInstanceId") final String vnfId) - throws InterruptedException { + @PostMapping(value = "/vnf_instances/{vnfInstanceId}/terminate") + public ResponseEntity terminateVnf(@PathVariable("vnfInstanceId") final String vnfId) { LOGGER.info("Start terminateVNFRequest"); final HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", MediaType.APPLICATION_JSON); return new ResponseEntity<>(svnfmService.terminateVnf(vnfId), headers, HttpStatus.ACCEPTED); } + + + /** + * To get the status of the operation by id + * + * @param operationId + * @return response entity + * @throws InterruptedException + */ + @GetMapping(value = "/vnf_lcm_op_occs/{vnfLcmOpOccId}") + public ResponseEntity getOperationStatus( + @PathVariable("vnfLcmOpOccId") final String operationId) { + LOGGER.info("Start getOperationStatus"); + final HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", MediaType.APPLICATION_JSON); + return new ResponseEntity<>(svnfmService.getOperationStatus(operationId), headers, HttpStatus.OK); + } + + @PostMapping(value = "/subscriptions") + public ResponseEntity subscribeForNotifications( + @RequestBody final LccnSubscriptionRequest lccnSubscriptionRequest) { + LOGGER.info("Subscription request received: {}", lccnSubscriptionRequest); + svnfmService.registerSubscription(lccnSubscriptionRequest); + final InlineResponse2001 response = new InlineResponse2001(); + + final HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + return new ResponseEntity<>(response, headers, HttpStatus.OK); + } } diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfJob.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfJob.java deleted file mode 100644 index 575223c700..0000000000 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfJob.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 Nordix Foundation. - * ================================================================================ - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ -package org.onap.svnfm.simulator.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -/** - * - * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) - * @author Ronan Kenny (ronan.kenny@est.tech) - */ -@Entity -@Table(name = "VNF_JOB") -public class VnfJob { - @Id - @Column(name = "jobId", nullable = false) - private String jobId; - private String vnfInstanceId; - private String vnfId; - private String status; - - public String getJobId() { - return jobId; - } - - public void setJobId(final String jobId) { - this.jobId = jobId; - } - - public String getVnfInstanceId() { - return vnfInstanceId; - } - - public void setVnfInstanceId(final String vnfInstanceId) { - this.vnfInstanceId = vnfInstanceId; - } - - public String getVnfId() { - return vnfId; - } - - public void setVnfId(final String vnfId) { - this.vnfId = vnfId; - } - - public String getStatus() { - return status; - } - - public void setStatus(final String status) { - this.status = status; - } -} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfOperation.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfOperation.java new file mode 100644 index 0000000000..c37f433668 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/VnfOperation.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ +package org.onap.svnfm.simulator.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; + +/** + * + * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) + * @author Ronan Kenny (ronan.kenny@est.tech) + */ +@Entity +@Table(name = "VNF_OPERATION") +public class VnfOperation { + @Id + @Column(name = "operationId", nullable = false) + private String id; + private String vnfInstanceId; + + @Enumerated(EnumType.STRING) + private InlineResponse200.OperationEnum operation; + + @Enumerated(EnumType.STRING) + private InlineResponse200.OperationStateEnum operationState; + + public String getId() { + return id; + } + + public void setId(final String id) { + this.id = id; + } + + public String getVnfInstanceId() { + return vnfInstanceId; + } + + public void setVnfInstanceId(final String vnfInstanceId) { + this.vnfInstanceId = vnfInstanceId; + } + + public InlineResponse200.OperationEnum getOperation() { + return operation; + } + + public void setOperation(final InlineResponse200.OperationEnum operation) { + this.operation = operation; + } + + public InlineResponse200.OperationStateEnum getOperationState() { + return operationState; + } + + public void setOperationState(final InlineResponse200.OperationStateEnum operationState) { + this.operationState = operationState; + } +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/Vnfds.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/Vnfds.java new file mode 100644 index 0000000000..ea171f0fce --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/model/Vnfds.java @@ -0,0 +1,97 @@ +package org.onap.svnfm.simulator.model; + +import java.util.List; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@ConfigurationProperties(prefix = "vnfds") +@Component +public class Vnfds { + + private List vnfdList; + + public static class Vnfd { + + private String vnfdId; + private List vnfclist; + + + public String getVnfdId() { + return vnfdId; + } + + public void setVnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + } + + public List getVnfcList() { + return vnfclist; + } + + public void setVnfcList(final List vnfclist) { + this.vnfclist = vnfclist; + } + } + + + public static class Vnfc { + + private String vnfcId; + private String type; + private String vduId; + private String resourceTemplateId; + private String grantResourceId; + + public String getVnfcId() { + return vnfcId; + } + + public void setVnfcId(final String vnfcId) { + this.vnfcId = vnfcId; + } + + public String getVduId() { + return vduId; + } + + public void setVduId(final String vduId) { + this.vduId = vduId; + } + + public String getType() { + return type; + } + + public void setType(final String type) { + this.type = type; + } + + public String getResourceTemplateId() { + return resourceTemplateId; + } + + public void setResourceTemplateId(final String resourceTemplateId) { + this.resourceTemplateId = resourceTemplateId; + } + + public String getGrantResourceId() { + return grantResourceId; + } + + public void setGrantResourceId(final String grantResourceId) { + this.grantResourceId = grantResourceId; + } + + } + + + public List getVnfdList() { + return vnfdList; + } + + + public void setVnfdList(final List vnfdList) { + this.vnfdList = vnfdList; + } + +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfJobRepository.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfJobRepository.java deleted file mode 100644 index b3b39bfdf1..0000000000 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfJobRepository.java +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2019 Nordix Foundation. - * ================================================================================ - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -package org.onap.svnfm.simulator.repository; - -import org.onap.svnfm.simulator.model.VnfJob; -import org.springframework.data.repository.CrudRepository; - -/** - * - * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) - * @author Ronan Kenny (ronan.kenny@est.tech) - */ -public interface VnfJobRepository extends CrudRepository { - -} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfOperationRepository.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfOperationRepository.java new file mode 100644 index 0000000000..43c201734f --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfOperationRepository.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.svnfm.simulator.repository; + +import org.onap.svnfm.simulator.model.VnfOperation; +import org.springframework.data.repository.CrudRepository; + +/** + * + * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) + * @author Ronan Kenny (ronan.kenny@est.tech) + */ +public interface VnfOperationRepository extends CrudRepository { + +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfmCacheRepository.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfmCacheRepository.java index e41cbe1e3a..030b073da4 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfmCacheRepository.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/repository/VnfmCacheRepository.java @@ -20,15 +20,21 @@ package org.onap.svnfm.simulator.repository; +import java.util.List; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201.InstantiationStateEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfo; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201VimConnectionInfo; +import org.onap.svnfm.simulator.constants.Constant; import org.onap.svnfm.simulator.services.SvnfmService; -import org.onap.vnfm.v1.model.CreateVnfRequest; -import org.onap.vnfm.v1.model.InlineResponse201; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Repository; /** - * + * * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) * @author Ronan Kenny (ronan.kenny@est.tech) */ @@ -38,12 +44,21 @@ public class VnfmCacheRepository { @Autowired private SvnfmService svnfmService; - @Cacheable(value = "inlineResponse201", key = "#createVnfRequest.vnfdId") - public InlineResponse201 createVnf(final CreateVnfRequest createVnfRequest) { - return svnfmService.createVnf(createVnfRequest); + @Cacheable(value = Constant.IN_LINE_RESPONSE_201_CACHE, key = "#id") + public InlineResponse201 createVnf(final CreateVnfRequest createVnfRequest, final String id) { + return svnfmService.createVnf(createVnfRequest, id); + } + + @CachePut(value = Constant.IN_LINE_RESPONSE_201_CACHE, key = "#id") + public InlineResponse201 updateVnf(final InlineResponse201InstantiatedVnfInfo instantiatedVnfInfo, final String id, + final List vimConnectionInfo) { + final InlineResponse201 vnf = getVnf(id); + vnf.setInstantiatedVnfInfo(instantiatedVnfInfo); + vnf.setInstantiationState(InstantiationStateEnum.INSTANTIATED); + vnf.setVimConnectionInfo(vimConnectionInfo); + return vnf; } - @Cacheable(value = "inlineResponse201", key = "#id") public InlineResponse201 getVnf(final String id) { return svnfmService.getVnf(id); } @@ -52,7 +67,7 @@ public class VnfmCacheRepository { * @param vnfId * @return */ - public InlineResponse201 deleteVnf(String vnfId) { + public InlineResponse201 deleteVnf(final String vnfId) { // TODO return null; } diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java new file mode 100644 index 0000000000..d231e1b098 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/OperationProgressor.java @@ -0,0 +1,296 @@ +package org.onap.svnfm.simulator.services; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.core.MediaType; +import org.apache.commons.codec.binary.Base64; +import org.modelmapper.ModelMapper; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiResponse; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsAddResources; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsAddResources.TypeEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinks; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinksVnfLcmOpOcc; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.InlineResponse201AddResources; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.InlineResponse201VimConnections; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiClient; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiException; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.api.DefaultApi; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.ChangeTypeEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinks; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationStatusEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationTypeEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfo; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoResourceHandle; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoVnfcResourceInfo; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201VimConnectionInfo; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic; +import org.onap.svnfm.simulator.config.ApplicationConfig; +import org.onap.svnfm.simulator.model.VnfOperation; +import org.onap.svnfm.simulator.model.Vnfds; +import org.onap.svnfm.simulator.model.Vnfds.Vnfc; +import org.onap.svnfm.simulator.model.Vnfds.Vnfd; +import org.onap.svnfm.simulator.repository.VnfOperationRepository; +import org.onap.svnfm.simulator.repository.VnfmCacheRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OperationProgressor implements Runnable { + + private static final Logger LOGGER = LoggerFactory.getLogger(OperationProgressor.class); + private final VnfOperation operation; + private final VnfmCacheRepository vnfRepository; + private final VnfOperationRepository vnfOperationRepository; + private final ApplicationConfig applicationConfig; + private final Vnfds vnfds; + private final SubscriptionService subscriptionService; + private final DefaultApi notificationClient; + private final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi grantClient; + + public OperationProgressor(final VnfOperation operation, final VnfmCacheRepository vnfRepository, + final VnfOperationRepository vnfOperationRepository, final ApplicationConfig applicationConfig, + final Vnfds vnfds, final SubscriptionService subscriptionService) { + this.operation = operation; + this.vnfRepository = vnfRepository; + this.vnfOperationRepository = vnfOperationRepository; + this.applicationConfig = applicationConfig; + this.vnfds = vnfds; + this.subscriptionService = subscriptionService; + + final ApiClient apiClient = new ApiClient(); + String callBackUrl = subscriptionService.getSubscriptions().iterator().next().getCallbackUri(); + callBackUrl = callBackUrl.substring(0, callBackUrl.indexOf("/lcn/")); + apiClient.setBasePath(callBackUrl); + notificationClient = new DefaultApi(apiClient); + + final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient grantApiClient = + new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient(); + grantApiClient.setBasePath(callBackUrl); + grantClient = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi(grantApiClient); + } + + @Override + public void run() { + try { + final VnfLcmOperationOccurrenceNotification notificationOfStarting = + buildNotification(NotificationStatusEnum.START, OperationStateEnum.STARTING); + sendNotification(notificationOfStarting); + + sleep(2000); + setState(InlineResponse200.OperationStateEnum.PROCESSING); + final VnfLcmOperationOccurrenceNotification notificationOfProcessing = + buildNotification(NotificationStatusEnum.START, OperationStateEnum.PROCESSING); + sendNotification(notificationOfProcessing); + + + final GrantRequest grantRequest = buildGrantRequest(); + final InlineResponse201 grantResponse = sendGrantRequest(grantRequest); + final InlineResponse201InstantiatedVnfInfo instantiatedVnfInfo = createInstantiatedVnfInfo(grantResponse); + vnfRepository.updateVnf(instantiatedVnfInfo, operation.getVnfInstanceId(), + getVimConnections(grantResponse)); + + sleep(10000); + setState(InlineResponse200.OperationStateEnum.COMPLETED); + final VnfLcmOperationOccurrenceNotification notificationOfCompleted = + buildNotification(NotificationStatusEnum.RESULT, OperationStateEnum.COMPLETED); + notificationOfCompleted.setAffectedVnfcs(getVnfcs(instantiatedVnfInfo.getVnfcResourceInfo())); + + sendNotification(notificationOfCompleted); + } catch (final Exception exception) { + LOGGER.error("Error in OperationProgressor ", exception); + } + + } + + private void sleep(final long milliSeconds) { + try { + Thread.sleep(milliSeconds); + } catch (final InterruptedException e) { + operation.setOperationState(InlineResponse200.OperationStateEnum.FAILED); + } + } + + private void setState(final InlineResponse200.OperationStateEnum state) { + LOGGER.info("Setting state to {} for operation {}", state, operation.getId()); + operation.setOperationState(state); + vnfOperationRepository.save(operation); + } + + private VnfLcmOperationOccurrenceNotification buildNotification(final NotificationStatusEnum status, + final OperationStateEnum operationState) { + final VnfLcmOperationOccurrenceNotification notification = new VnfLcmOperationOccurrenceNotification(); + notification.setId(UUID.randomUUID().toString()); + notification.setNotificationType(NotificationTypeEnum.VNFLCMOPERATIONOCCURRENCENOTIFICATION); + notification.setNotificationStatus(status); + notification.setOperationState(operationState); + notification.setOperation(OperationEnum.fromValue(operation.getOperation().toString())); + notification.setVnfInstanceId(operation.getVnfInstanceId()); + + final LcnVnfLcmOperationOccurrenceNotificationLinks links = new LcnVnfLcmOperationOccurrenceNotificationLinks(); + final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance vnfInstanceLink = + new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance(); + vnfInstanceLink.setHref(getVnfLink()); + links.setVnfInstance(vnfInstanceLink); + + + final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance operationLink = + new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance(); + operationLink.setHref(getOperationLink()); + links.setVnfLcmOpOcc(operationLink); + + notification.setLinks(links); + + return notification; + } + + private List getVnfcs( + final List instantiatedVnfcs) { + final List vnfcs = new ArrayList<>(); + for (final InlineResponse201InstantiatedVnfInfoVnfcResourceInfo instantiatedVnfc : instantiatedVnfcs) { + LOGGER.info("VNFC TO BE CONVERTED: {}", instantiatedVnfc); + final ModelMapper mapper = new ModelMapper(); + final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc = + mapper.map(instantiatedVnfc, LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.class); + LOGGER.info("VNFC FROM CONVERSION: {}", vnfc); + vnfc.setChangeType(ChangeTypeEnum.ADDED); + vnfcs.add(vnfc); + } + return vnfcs; + } + + private void sendNotification(final VnfLcmOperationOccurrenceNotification notification) { + LOGGER.info("Sending notification: {}", notification); + try { + final SubscriptionsAuthenticationParamsBasic subscriptionAuthentication = + subscriptionService.getSubscriptions().iterator().next().getAuthentication().getParamsBasic(); + final String auth = + subscriptionAuthentication.getUserName() + ":" + subscriptionAuthentication.getPassword(); + final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1)); + final String authHeader = "Basic " + new String(encodedAuth); + notificationClient.lcnVnfLcmOperationOccurrenceNotificationPostWithHttpInfo(notification, + MediaType.APPLICATION_JSON, authHeader); + } catch (final ApiException exception) { + LOGGER.error("Error sending notification: " + notification, exception); + } + } + + + public GrantRequest buildGrantRequest() { + final GrantRequest grantRequest = new GrantRequest(); + grantRequest.setVnfInstanceId(operation.getVnfInstanceId()); + final String vnfdId = vnfRepository.getVnf(operation.getVnfInstanceId()).getVnfdId(); + grantRequest.setVnfdId(vnfdId); + grantRequest.setAddResources(getAddResources(vnfdId)); + grantRequest.setVnfLcmOpOccId(operation.getId()); + grantRequest + .setOperation(org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest.OperationEnum + .fromValue(operation.getOperation().getValue())); + grantRequest.setIsAutomaticInvocation(false); + + final GrantsLinksVnfLcmOpOcc vnfInstanceLink = new GrantsLinksVnfLcmOpOcc(); + vnfInstanceLink.setHref(getVnfLink()); + final GrantsLinksVnfLcmOpOcc operationInstanceLink = new GrantsLinksVnfLcmOpOcc(); + operationInstanceLink.setHref(getOperationLink()); + final GrantsLinks links = new GrantsLinks(); + links.setVnfInstance(vnfInstanceLink); + links.setVnfLcmOpOcc(operationInstanceLink); + grantRequest.setLinks(links); + return grantRequest; + } + + private List getAddResources(final String vnfdId) { + final List resources = new ArrayList<>(); + + for (final Vnfd vnfd : vnfds.getVnfdList()) { + if (vnfd.getVnfdId().equals(vnfdId)) { + for (final Vnfc vnfc : vnfd.getVnfcList()) { + final GrantsAddResources addResource = new GrantsAddResources(); + vnfc.setGrantResourceId(UUID.randomUUID().toString()); + addResource.setId(vnfc.getGrantResourceId()); + addResource.setType(TypeEnum.fromValue(vnfc.getType())); + addResource.setResourceTemplateId(vnfc.getResourceTemplateId()); + addResource.setVduId(vnfc.getVduId()); + resources.add(addResource); + } + } + } + return resources; + } + + private InlineResponse201 sendGrantRequest(final GrantRequest grantRequest) { + LOGGER.info("Sending grant request: {}", grantRequest); + try { + final ApiResponse response = grantClient.grantsPostWithHttpInfo(grantRequest, + MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, "Basic dm5mbTpwYXNzd29yZDEk"); + LOGGER.info("Grant Response: {}", response); + return response.getData(); + } catch (final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiException exception) { + LOGGER.error("Error sending notification: " + grantRequest, exception); + return null; + } + } + + private InlineResponse201InstantiatedVnfInfo createInstantiatedVnfInfo(final InlineResponse201 grantResponse) { + final InlineResponse201InstantiatedVnfInfo instantiatedVnfInfo = new InlineResponse201InstantiatedVnfInfo(); + + final Map mapOfGrantResourceIdToVimConnectionId = new HashMap<>(); + for (final InlineResponse201AddResources addResource : grantResponse.getAddResources()) { + mapOfGrantResourceIdToVimConnectionId.put(addResource.getResourceDefinitionId(), + addResource.getVimConnectionId()); + } + + for (final Vnfd vnfd : vnfds.getVnfdList()) { + if (vnfd.getVnfdId().equals(vnfRepository.getVnf(operation.getVnfInstanceId()).getVnfdId())) { + for (final Vnfc vnfc : vnfd.getVnfcList()) { + final InlineResponse201InstantiatedVnfInfoVnfcResourceInfo vnfcResourceInfoItem = + new InlineResponse201InstantiatedVnfInfoVnfcResourceInfo(); + vnfcResourceInfoItem.setId(vnfc.getVnfcId()); + vnfcResourceInfoItem.setVduId(vnfc.getVduId()); + final InlineResponse201InstantiatedVnfInfoResourceHandle computeResource = + new InlineResponse201InstantiatedVnfInfoResourceHandle(); + computeResource.setResourceId(UUID.randomUUID().toString()); + computeResource + .setVimConnectionId(mapOfGrantResourceIdToVimConnectionId.get(vnfc.getGrantResourceId())); + computeResource.setVimLevelResourceType("OS::Nova::Server"); + vnfcResourceInfoItem.setComputeResource(computeResource); + instantiatedVnfInfo.addVnfcResourceInfoItem(vnfcResourceInfoItem); + } + } + } + + return instantiatedVnfInfo; + } + + private List getVimConnections(final InlineResponse201 grantResponse) { + final List vimConnectionInfo = new ArrayList<>(); + for (final InlineResponse201VimConnections vimConnection : grantResponse.getVimConnections()) { + final ModelMapper modelMapper = new ModelMapper(); + vimConnectionInfo.add(modelMapper.map(vimConnection, InlineResponse201VimConnectionInfo.class)); + } + return vimConnectionInfo; + } + + private String getVnfLink() { + return getLinkBaseUrl() + "/vnf_instances/" + operation.getVnfInstanceId(); + } + + private String getOperationLink() { + return getLinkBaseUrl() + "/vnf_lcm_op_occs/" + operation.getId(); + } + + private String getLinkBaseUrl() { + return applicationConfig.getBaseUrl() + "/vnflcm/v1"; + } + +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SubscriptionService.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SubscriptionService.java new file mode 100644 index 0000000000..6a2340bdf6 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SubscriptionService.java @@ -0,0 +1,21 @@ +package org.onap.svnfm.simulator.services; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest; +import org.springframework.stereotype.Service; + +@Service +public class SubscriptionService { + + Collection subscriptions = new ArrayList<>(); + + public void registerSubscription(final LccnSubscriptionRequest subscription) { + subscriptions.add(subscription); + } + + public Collection getSubscriptions() { + return Collections.unmodifiableCollection(subscriptions); + } +} diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SvnfmService.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SvnfmService.java index f7f4eaa4a2..cac5075682 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SvnfmService.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/SvnfmService.java @@ -21,22 +21,35 @@ package org.onap.svnfm.simulator.services; import java.lang.reflect.InvocationTargetException; -import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.modelmapper.ModelMapper; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest; +import org.onap.svnfm.simulator.config.ApplicationConfig; +import org.onap.svnfm.simulator.constants.Constant; import org.onap.svnfm.simulator.model.VnfInstance; -import org.onap.svnfm.simulator.model.VnfJob; +import org.onap.svnfm.simulator.model.VnfOperation; +import org.onap.svnfm.simulator.model.Vnfds; import org.onap.svnfm.simulator.notifications.VnfInstantiationNotification; import org.onap.svnfm.simulator.notifications.VnfmAdapterCreationNotification; -import org.onap.svnfm.simulator.repository.VnfJobRepository; +import org.onap.svnfm.simulator.repository.VnfOperationRepository; +import org.onap.svnfm.simulator.repository.VnfmCacheRepository; import org.onap.svnfm.simulator.repository.VnfmRepository; -import org.onap.vnfm.v1.model.CreateVnfRequest; -import org.onap.vnfm.v1.model.InlineResponse201; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.support.SimpleValueWrapper; import org.springframework.stereotype.Service; /** - * + * * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) * @author Ronan Kenny (ronan.kenny@est.tech) */ @@ -47,27 +60,44 @@ public class SvnfmService { VnfmRepository vnfmRepository; @Autowired - VnfJobRepository vnfJobRepository; + VnfmCacheRepository vnfRepository; + + @Autowired + VnfOperationRepository vnfOperationRepository; @Autowired private VnfmHelper vnfmHelper; + @Autowired + ApplicationConfig applicationConfig; + + @Autowired + CacheManager cacheManager; + + @Autowired + Vnfds vnfds; + + @Autowired + SubscriptionService subscriptionService; + + private final ExecutorService executor = Executors.newCachedThreadPool(); + private static final Logger LOGGER = LoggerFactory.getLogger(SvnfmService.class); /** - * + * * @param createVNFRequest * @return inlineResponse201 */ - public InlineResponse201 createVnf(final CreateVnfRequest createVNFRequest) { + public InlineResponse201 createVnf(final CreateVnfRequest createVNFRequest, final String id) { InlineResponse201 inlineResponse201 = null; try { - final VnfInstance vnfInstance = vnfmHelper.createVnfInstance(createVNFRequest); + final VnfInstance vnfInstance = vnfmHelper.createVnfInstance(createVNFRequest, id); vnfmRepository.save(vnfInstance); final Thread creationNotification = new Thread(new VnfmAdapterCreationNotification()); creationNotification.start(); inlineResponse201 = vnfmHelper.getInlineResponse201(vnfInstance); - LOGGER.debug("Response from Create VNF", inlineResponse201); + LOGGER.debug("Response from Create VNF {}", inlineResponse201); } catch (IllegalAccessException | InvocationTargetException e) { LOGGER.error("Failed in Create Vnf", e); } @@ -75,94 +105,80 @@ public class SvnfmService { } /** - * + * * @param vnfId - * @param instantiateJobId + * @param instantiateVNFRequest + * @param operationId * @throws InterruptedException */ - public Object instatiateVnf(final String vnfId, final String instantiateJobId) throws InterruptedException { - final VnfJob vnfJob = buildVnfInstantiation(vnfId, instantiateJobId); - vnfJobRepository.save(vnfJob); - getJobStatus(vnfJob.getJobId()); - return null; + public String instantiateVnf(final String vnfId, final InstantiateVnfRequest instantiateVNFRequest) { + final VnfOperation vnfOperation = buildVnfOperation(InlineResponse200.OperationEnum.INSTANTIATE, vnfId); + vnfOperationRepository.save(vnfOperation); + executor.submit(new OperationProgressor(vnfOperation, vnfRepository, vnfOperationRepository, applicationConfig, + vnfds, subscriptionService)); + return vnfOperation.getId(); } /** - * + * vnfOperationRepository + * * @param vnfId - * @param instantiateJobId + * @param instantiateOperationId */ - public VnfJob buildVnfInstantiation(final String vnfId, final String instantiateJobId) { - final VnfJob vnfJob = new VnfJob(); - final Optional vnfInstance = vnfmRepository.findById(vnfId); - - if (vnfInstance.isPresent()) { - vnfJob.setJobId(instantiateJobId); - for (final VnfInstance instance : vnfmRepository.findAll()) { - if (instance.getId().equals(vnfId)) { - vnfJob.setVnfInstanceId(instance.getVnfInstanceDescription()); - } - } - vnfJob.setVnfId(vnfId); - vnfJob.setStatus("STARTING"); - } - return vnfJob; + public VnfOperation buildVnfOperation(final InlineResponse200.OperationEnum operation, final String vnfId) { + final VnfOperation vnfOperation = new VnfOperation(); + vnfOperation.setId(UUID.randomUUID().toString()); + vnfOperation.setOperation(operation); + vnfOperation.setOperationState(InlineResponse200.OperationStateEnum.STARTING); + vnfOperation.setVnfInstanceId(vnfId); + return vnfOperation; } /** - * - * @param jobId + * + * @param operationId * @throws InterruptedException */ - public Object getJobStatus(final String jobId) throws InterruptedException { - LOGGER.info("Getting job status with id: " + jobId); - for (int i = 0; i < 5; i++) { - LOGGER.info("Instantiation status: RUNNING"); - Thread.sleep(5000); - for (final VnfJob job : vnfJobRepository.findAll()) { - if (job.getJobId().equals(jobId)) { - job.setStatus("RUNNING"); - vnfJobRepository.save(job); - } - } - } + public InlineResponse200 getOperationStatus(final String operationId) { + LOGGER.info("Getting operation status with id: {}", operationId); final Thread instantiationNotification = new Thread(new VnfInstantiationNotification()); instantiationNotification.start(); - for (final VnfJob job : vnfJobRepository.findAll()) { - if (job.getJobId().equals(jobId)) { - job.setStatus("COMPLETE"); - vnfJobRepository.save(job); + for (final VnfOperation operation : vnfOperationRepository.findAll()) { + LOGGER.info("Operation found: {}", operation); + if (operation.getId().equals(operationId)) { + final ModelMapper modelMapper = new ModelMapper(); + return modelMapper.map(operation, InlineResponse200.class); } } return null; } /** - * + * * @param vnfId * @return inlineResponse201 */ public InlineResponse201 getVnf(final String vnfId) { - InlineResponse201 inlineResponse201 = null; - - final Optional vnfInstance = vnfmRepository.findById(vnfId); - try { - if (vnfInstance.isPresent()) { - inlineResponse201 = vnfmHelper.getInlineResponse201(vnfInstance.get()); - LOGGER.debug("Response from get VNF", inlineResponse201); - } - } catch (IllegalAccessException | InvocationTargetException e) { - LOGGER.error("Failed in get Vnf", e); + final Cache ca = cacheManager.getCache(Constant.IN_LINE_RESPONSE_201_CACHE); + final SimpleValueWrapper wrapper = (SimpleValueWrapper) ca.get(vnfId); + final InlineResponse201 inlineResponse201 = (InlineResponse201) wrapper.get(); + if (inlineResponse201 != null) { + LOGGER.info("Cache Read Successful"); + return inlineResponse201; } - return inlineResponse201; + return null; } /** * @param vnfId * @return */ - public Object terminateVnf(String vnfId) { + public Object terminateVnf(final String vnfId) { // TODO return null; } + + public void registerSubscription(final LccnSubscriptionRequest subscription) { + subscriptionService.registerSubscription(subscription); + } } diff --git a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/VnfmHelper.java b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/VnfmHelper.java index f35cbf2f49..7c038b823f 100644 --- a/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/VnfmHelper.java +++ b/vnfm-simulator/vnfm-service/src/main/java/org/onap/svnfm/simulator/services/VnfmHelper.java @@ -22,30 +22,36 @@ package org.onap.svnfm.simulator.services; import java.lang.reflect.InvocationTargetException; import org.apache.commons.beanutils.BeanUtils; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201.InstantiationStateEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201Links; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201LinksSelf; +import org.onap.svnfm.simulator.config.ApplicationConfig; import org.onap.svnfm.simulator.constants.Constant; import org.onap.svnfm.simulator.model.VnfInstance; -import org.onap.vnfm.v1.model.CreateVnfRequest; -import org.onap.vnfm.v1.model.InlineResponse201; -import org.onap.vnfm.v1.model.InlineResponse201.InstantiationStateEnum; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** - * + * * @author Lathishbabu Ganesan (lathishbabu.ganesan@est.tech) * @author Ronan Kenny (ronan.kenny@est.tech) */ @Component public class VnfmHelper { + @Autowired + private ApplicationConfig applicationConfig; + /** - * + * * @param createVNFRequest * @return vnfInstance */ - public VnfInstance createVnfInstance(final CreateVnfRequest createVNFRequest) { + public VnfInstance createVnfInstance(final CreateVnfRequest createVNFRequest, final String id) { final VnfInstance vnfInstance = new VnfInstance(); - final String vnfId = createVNFRequest.getVnfdId(); - vnfInstance.setId(vnfId); + vnfInstance.setId(id); vnfInstance.setVnfInstanceName(createVNFRequest.getVnfInstanceName()); vnfInstance.setVnfInstanceDescription(createVNFRequest.getVnfInstanceDescription()); vnfInstance.setVnfdId(createVNFRequest.getVnfdId()); @@ -55,7 +61,7 @@ public class VnfmHelper { } /** - * + * * @param vnfInstance * @return inlineResponse201 * @throws IllegalAccessException @@ -68,6 +74,21 @@ public class VnfmHelper { inlineResponse201.setVnfdVersion(Constant.VNFD_VERSION); inlineResponse201.setVnfSoftwareVersion(Constant.VNF_SOFTWARE_VERSION); inlineResponse201.setInstantiationState(InstantiationStateEnum.NOT_INSTANTIATED); + inlineResponse201.setVnfConfigurableProperties(Constant.VNF_CONFIG_PROPERTIES); + addAdditionalPRopertyInlineResponse201(inlineResponse201); return inlineResponse201; } + + private void addAdditionalPRopertyInlineResponse201(final InlineResponse201 inlineResponse201) { + final InlineResponse201LinksSelf VnfInstancesLinksSelf = new InlineResponse201LinksSelf(); + VnfInstancesLinksSelf + .setHref(applicationConfig.getBaseUrl() + "/vnflcm/v1/vnf_instances/" + inlineResponse201.getId()); + final InlineResponse201LinksSelf VnfInstancesLinksSelfInstantiate = new InlineResponse201LinksSelf(); + VnfInstancesLinksSelfInstantiate.setHref(applicationConfig.getBaseUrl() + "/vnflcm/v1/vnf_instances/" + + inlineResponse201.getId() + "/instantiate"); + final InlineResponse201Links inlineResponse201Links = new InlineResponse201Links(); + inlineResponse201Links.setSelf(VnfInstancesLinksSelf); + inlineResponse201Links.setInstantiate(VnfInstancesLinksSelfInstantiate); + inlineResponse201.setLinks(inlineResponse201Links); + } } diff --git a/vnfm-simulator/vnfm-service/src/main/resources/application.properties b/vnfm-simulator/vnfm-service/src/main/resources/application.properties deleted file mode 100644 index c5b36d77f4..0000000000 --- a/vnfm-simulator/vnfm-service/src/main/resources/application.properties +++ /dev/null @@ -1,13 +0,0 @@ -# Enabling H2 Console -spring.h2.console.enabled=true -spring.h2.console.path=/console -spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=admin -spring.datasource.password=admin -spring.datasource.driverClassName=org.h2.Driver -spring.jpa.hibernate.ddl-auto = update -spring.jpa.show-sql=true -logging.level.org.hibernate.SQL=DEBUG -logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE - -server.port=9081 \ No newline at end of file diff --git a/vnfm-simulator/vnfm-service/src/main/resources/application.yaml b/vnfm-simulator/vnfm-service/src/main/resources/application.yaml new file mode 100644 index 0000000000..2ef302ce25 --- /dev/null +++ b/vnfm-simulator/vnfm-service/src/main/resources/application.yaml @@ -0,0 +1,59 @@ +# Copyright © 2019 Nordix Foundation +# +# 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. + +spring: + h2: + console: + enabled: true + path: console + datasource: + url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE + username: admin + password: admin + http: + converters: + preferred-json-mapper: gson + security: + usercredentials: + - username: vnfm + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: BPEL-Client + +server: + port: 9093 + tomcat: + max-threads: 50 + +vnfds: + vnfdlist: + - vnfdid: 1 + vnfclist: + - vnfcid: VNFC1 + resourceTemplateId: vnfd1_vnfc1 + vduId: vnfd1_vduForVnfc1 + type: COMPUTE + - vnfcid: VNFC2 + resourceTemplateId: vnfd1_vnfc2 + vduId: vnfd1_vduForVnfc2 + type: COMPUTE + - vnfdid: 2 + vnfclist: + - vnfcid: VNFC3 + resourceTemplateId: vnfd2_vnfc3 + vduId: vnfd2_vduForVnfc3 + type: COMPUTE + - vnfcid: VNFC4 + resourceTemplateId: vnfd2_vnfc4 + vduId: vnfd2_vduForVnfc4 + type: COMPUTE \ No newline at end of file diff --git a/vnfm-simulator/vnfm-service/src/test/java/org/onap/svnfm/simulator/controllers/TestSvnfmController.java b/vnfm-simulator/vnfm-service/src/test/java/org/onap/svnfm/simulator/controllers/TestSvnfmController.java index f338b5828e..9cb0702ee0 100644 --- a/vnfm-simulator/vnfm-service/src/test/java/org/onap/svnfm/simulator/controllers/TestSvnfmController.java +++ b/vnfm-simulator/vnfm-service/src/test/java/org/onap/svnfm/simulator/controllers/TestSvnfmController.java @@ -20,10 +20,13 @@ package org.onap.svnfm.simulator.controllers; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,15 +34,15 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.CreateVnfRequest; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.svnfm.simulator.constants.Constant; import org.onap.svnfm.simulator.controller.SvnfmController; import org.onap.svnfm.simulator.repository.VnfmCacheRepository; import org.onap.svnfm.simulator.services.SvnfmService; -import org.onap.vnfm.v1.model.CreateVnfRequest; -import org.onap.vnfm.v1.model.InlineResponse201; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(MockitoJUnitRunner.class) public class TestSvnfmController { @@ -69,14 +72,12 @@ public class TestSvnfmController { createVnfRequest.setVnfInstanceName("createVnfInstanceTest"); createVnfRequest.setVnfInstanceDescription("createVnfInstanceTest"); - when(vnfmCacheRepository.createVnf(createVnfRequest)).thenReturn(new InlineResponse201()); - - svnfmService.createVnf(createVnfRequest); + when(vnfmCacheRepository.createVnf(eq(createVnfRequest), anyString())).thenReturn(new InlineResponse201()); final String body = (new ObjectMapper()).valueToTree(createVnfRequest).toString(); this.mockMvc - .perform(post("/svnfm/vnf_instances").content(body).contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) + .perform(post(Constant.BASE_URL + "/vnf_instances").content(body) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()).andExpect(content().contentType(MediaType.APPLICATION_JSON)); } } -- cgit 1.2.3-korg