diff options
61 files changed, 1630 insertions, 348 deletions
diff --git a/docs/humaninterfaces.rst b/docs/humaninterfaces.rst index 25c7b5d7e..97ae05d25 100644 --- a/docs/humaninterfaces.rst +++ b/docs/humaninterfaces.rst @@ -13,3 +13,8 @@ The following VID user guides are available on the ONAP Wiki: - `VID Application Overview <https://wiki.onap.org/display/DW/VID>`_ - `Gather and validate data for an infrastructure service/network <https://wiki.onap.org/pages/viewpage.action?pageId=1019313>`_ - `Instantiate an infrastructure service <https://wiki.onap.org/display/DW/Instantiate+an+infrastructure+service>`_ + +.. toctree:: + :maxdepth: 1 + + instantiate.rst diff --git a/docs/images/API_selection.png b/docs/images/API_selection.png Binary files differnew file mode 100755 index 000000000..46b125a7b --- /dev/null +++ b/docs/images/API_selection.png diff --git a/docs/images/browse-service-models.png b/docs/images/browse-service-models.png Binary files differnew file mode 100755 index 000000000..d582d6935 --- /dev/null +++ b/docs/images/browse-service-models.png diff --git a/docs/images/create-network-instance-alacarte-after-instantiated.png b/docs/images/create-network-instance-alacarte-after-instantiated.png Binary files differnew file mode 100755 index 000000000..cf1b99566 --- /dev/null +++ b/docs/images/create-network-instance-alacarte-after-instantiated.png diff --git a/docs/images/create-network-instance-alacarte.png b/docs/images/create-network-instance-alacarte.png Binary files differnew file mode 100755 index 000000000..cadcdc0f5 --- /dev/null +++ b/docs/images/create-network-instance-alacarte.png diff --git a/docs/images/create-service-instance-alacarte-VNF-network.png b/docs/images/create-service-instance-alacarte-VNF-network.png Binary files differnew file mode 100755 index 000000000..73b77eea0 --- /dev/null +++ b/docs/images/create-service-instance-alacarte-VNF-network.png diff --git a/docs/images/create-service-instance-alacarte-after-vfmodule-instantiated.png b/docs/images/create-service-instance-alacarte-after-vfmodule-instantiated.png Binary files differnew file mode 100755 index 000000000..17a74f77c --- /dev/null +++ b/docs/images/create-service-instance-alacarte-after-vfmodule-instantiated.png diff --git a/docs/images/create-service-instance-alacarte-after-vnf-instantiated.png b/docs/images/create-service-instance-alacarte-after-vnf-instantiated.png Binary files differnew file mode 100755 index 000000000..97a363ef6 --- /dev/null +++ b/docs/images/create-service-instance-alacarte-after-vnf-instantiated.png diff --git a/docs/images/create-service-instance-alacarte-success.png b/docs/images/create-service-instance-alacarte-success.png Binary files differnew file mode 100755 index 000000000..e5dcd9768 --- /dev/null +++ b/docs/images/create-service-instance-alacarte-success.png diff --git a/docs/images/create-service-instance-alacarte.png b/docs/images/create-service-instance-alacarte.png Binary files differnew file mode 100755 index 000000000..e96c3adfd --- /dev/null +++ b/docs/images/create-service-instance-alacarte.png diff --git a/docs/images/create-vfmodule-instance-alacarte.png b/docs/images/create-vfmodule-instance-alacarte.png Binary files differnew file mode 100755 index 000000000..278fc5083 --- /dev/null +++ b/docs/images/create-vfmodule-instance-alacarte.png diff --git a/docs/images/create-vnf-instance-alacarte-success.png b/docs/images/create-vnf-instance-alacarte-success.png Binary files differnew file mode 100755 index 000000000..d0a7895a0 --- /dev/null +++ b/docs/images/create-vnf-instance-alacarte-success.png diff --git a/docs/images/create-vnf-instance-alacarte.png b/docs/images/create-vnf-instance-alacarte.png Binary files differnew file mode 100755 index 000000000..d4a9b216a --- /dev/null +++ b/docs/images/create-vnf-instance-alacarte.png diff --git a/docs/images/delete-service-instance.png b/docs/images/delete-service-instance.png Binary files differnew file mode 100755 index 000000000..aeda9bdd6 --- /dev/null +++ b/docs/images/delete-service-instance.png diff --git a/docs/images/home.png b/docs/images/home.png Binary files differnew file mode 100755 index 000000000..97f8b769d --- /dev/null +++ b/docs/images/home.png diff --git a/docs/images/onap-portal.png b/docs/images/onap-portal.png Binary files differnew file mode 100755 index 000000000..a58b44736 --- /dev/null +++ b/docs/images/onap-portal.png diff --git a/docs/images/service-instance-details.png b/docs/images/service-instance-details.png Binary files differnew file mode 100755 index 000000000..6d12aa682 --- /dev/null +++ b/docs/images/service-instance-details.png diff --git a/docs/images/vid-icon-on-portal.png b/docs/images/vid-icon-on-portal.png Binary files differnew file mode 100755 index 000000000..50ea1179e --- /dev/null +++ b/docs/images/vid-icon-on-portal.png diff --git a/docs/images/vnf-instance-detail.png b/docs/images/vnf-instance-detail.png Binary files differnew file mode 100755 index 000000000..bdff1fd15 --- /dev/null +++ b/docs/images/vnf-instance-detail.png diff --git a/docs/instantiate.rst b/docs/instantiate.rst new file mode 100644 index 000000000..66276def3 --- /dev/null +++ b/docs/instantiate.rst @@ -0,0 +1,418 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 + International License. +.. http://creativecommons.org/licenses/by/4.0 + +Instantiate Service, VNF, VF modules and Network +================================================ + + +Overview +-------- + +Using VID with A-La-Carte method means that the user needs to performed +by himself the instantiation of each object : service, VNF(s), VF module(s), +network(s). + +ONAP to VIM interactions will occurs when instantiating/deleting VF module(s) +or Network(s). In case of an Openstack VIM, Heat Stack(s) will +be created/deleted. + +In the following description, the service model in SDC was composed of 1 VF +and 1 Virtual Link (Generic Neutron Network) + +To be able to instantiate VF-module or Network object, some data need to be +declared in ONAP SDNC using SDNC Rest API. It is the place where to put +the instance specific values such as an IP address value specific +to the VNF instance for example. + +In VID, terminologies are sometimes different than in other components: + +VNF in VID = VF in SDC + +Node instance = VF in SDC + +Network = Virtual Link in SDC + + +Pre-requisites +-------------- + +pre-instantiation operations must have been performed in AAI and VID, +via Rest API, to declare some values for: + +- Subscriber Name (= customer in AAI) +- Service Type or product family (= service subscription in AAI) +- Project +- Owning Entity +- Line Of Business +- Platform +- LCP Region (= CloudOwner/RegionId in AAI) +- Tenant + +see, in the ONAP User Guides, section about adding a CloudSite +and section about pre-instantiation Operations + + +Access to VID portal +-------------------- + +.. figure:: images/onap-portal.png + :align: center + +Select the VID icon + +.. figure:: images/vid-icon-on-portal.png + :align: center + + +Here after, the VID Home page starts + +.. figure:: images/home.png + :align: center + + +SDNC API selection +------------------ + +Select the API for "A-la-carte" + +There are two choices: + +- VNF_API (old) : VID will use the (old) "VNF" SDNC API + to get/check some parameters +- GR_API (new) : VID will use the "Generic Resource" + SDNC API to get/check some parameters + +.. figure:: images/API_selection.png + :align: center + + + +Instantiate Service +------------------- + +Click Browse SDC Service Models and search for the service to instantiate. + +The view show only service models in the DISTRIBUTED state. + +.. figure:: images/browse-service-models.png + :align: center + + +Select a service and click Deploy. + +A dialog box displays. + +Complete the fields indicated by the red star and click Confirm. + +.. figure:: images/create-service-instance-alacarte.png + :align: center + +A status ox appears that shows the ONAP SO instantiation progress +as well as any messages associated with the process. + +.. figure:: images/create-service-instance-alacarte-success.png + :align: center + +A Service object is created in ONAP. + +Click Close and next screen should appear. +It will allow to declare VNF(s) and Network(s) +that are part of the service model composition. + +.. figure:: images/create-service-instance-alacarte-VNF-network.png + :align: center + + +Instantiate a VNF +----------------- + +From previous screen, it is possible to declare a VNF: click on +"Add node instance" and select the VNF you want to instantiate in the list + +The following screen should appear: + +.. figure:: images/create-vnf-instance-alacarte.png + :align: center + +Complete the fields indicated by the red star and click Confirm. + +A VNF object will be declared in ONAP. + +Once, ONAP SO process is finished, click on close button. + +The following screen then should appear: + + +.. figure:: images/create-service-instance-alacarte-after-vnf-instantiated.png + :align: center + + +Warning: a this step, no VNF instance (e.g. VM) is created on the Cloud Platform. + +Click on "i" blue button to obtain VNF instance display information. + +From this screen, it will be possible to get: + +- the service instance id value +- the VNF Type value + +Those information will be necessary for the "SDNC preload" step +to instantiate the VF module + +Close that screen + + +Instantiate VF Module +--------------------- + +It is now possible to declare a VF Module: click on +"Add VF-Module" and select the VF-module you want to instantiate in the list + +The following screen should appear: + +.. figure:: images/create-vfmodule-instance-alacarte.png + :align: center + +From this screen, it will be possible to get: + +- "Model Name" value + +At this step, with this "A-La-Carte" method, it is necessary to declare +some information in ONAP SDNC. + +SDNC needs to be aware about the VNF before trying to use ONAP SO +to instantiate the VF-module. + +This group of data is usually called "SDNC preload" and will contain: + +- vf-module instance Name +- vnf instance Name +- service instance id +- the list of vnf parameters with values, when not using the default values + +Here is an example of SDNC preload for VNF, using "curl" tool +to push those data using SDNC Rest API: + +:: + + curl -X POST \ + http://sdnc.api.simpledemo.onap.org:30202/restconf/operations/VNF-API:preload-vnf-topology-operation \ + -H 'Accept: application/json' \ + -H 'Authorization: Basic YWRtaW46S3A4Yko0U1hzek0wV1hsaGFrM2VIbGNzZTJnQXc4NHZhb0dHbUp2VXkyVQ==' \ + -H 'Content-Type: application/json' \ + -H 'X-FromAppId: API client' \ + -H 'X-TransactionId: 0a3f6713-ba96-4971-a6f8-c2da85a3176e' \ + -H 'cache-control: no-cache' \ + -d '{ + "input": { + "request-information": { + "notification-url": "onap.org", + "order-number": "1", + "order-version": "1", + "request-action": "PreloadVNFRequest", + "request-id": "test" + }, + "sdnc-request-header": { + "svc-action": "reserve", + "svc-notification-url": "http:\/\/onap.org:8080\/adapters\/rest\/SDNCNotify", + "svc-request-id": "test" + }, + "vnf-topology-information": { + "vnf-assignments": { + "availability-zones": [], + "vnf-networks": [], + "vnf-vms": [] + }, + "vnf-parameters": [ + { + "name": "oam_net_id", + "value": "oam_network_tXWW" + } + ], + "vnf-topology-identifier": { + "generic-vnf-name": "my-vnf-instance-01", + "generic-vnf-type": "Service-model-with-VNF-and-Virtual-Link/FreeRadius_VF 0", + "service-type": "09f9ffad-1069-43fa-97e8-da7b9a439601", + "vnf-name": "my_vf_module-instance-01", + "vnf-type": "FreeradiusVf..base_freeRadius..module-0" + } + } + } + } + ' + + +Data mapping between ONAP SDNC terminology and ONAP SO + +- "generic-vnf-name" value must be equal to the VNF instance name value + (see VNF instance detail screen) +- "generic-vnf-type" value must be equal to VNF Type value + (see VNF instance detail screen) +- "service-type" value must be equal to the service instance id value + (see VNF instance detail screen) +- "vnf-name" value must be equal to the VF module instance name value +- "vnf-type" value must be equal to the "Model Name" value + (see create VF module screen) + + +If there is a need for an instance specific value +of a VNF parameter (for example : an OAM network id value, +specific to this VNF instance), +the "vnf-parameters" must be completed with a list of name/value. + +Once the "SDNC preload" is completed, send it to SDNC using any Rest API Tool. + +Then, continue on VID and complete the fields indicated by the red star +and click "Confirm". + +Warning : be very careful to use exactly the same VF module instance name +on this screen and in the "SDNC preload" + +Wait for success and close the popup screen. + +The following screen should appear: + +.. figure:: images/create-service-instance-alacarte-after-vfmodule-instantiated.png + :align: center + +At that point, the VNF is now instantiated in the cloud platform. + + +Instantiate Network +------------------- + +Instantiating a network is quite similar to vf-module instantiation +(there is also the need for a "SDNC preload") + +Click on "Add Network" and select the Network you want +to instantiate in the list + +The following screen should appear: + +.. figure:: images/create-network-instance-alacarte.png + :align: center + + +Prepare the "SDNC preload" with: + +- "network-role": provide any value, +- "network-technology": use "neutron" as this example will instantiate + a network using openstack neutron application +- "service-type": value must be equal to "Service Name" + (=service model name) displayed on VID screen +- "network-name": value must be equal to the desired network instance name, +- "network-type": value must be equal to "Model Name""Generic NeutronNet" + displayed on VID screen + +In addition: + +- in "provider-network-information" section, it is possible to indicate + some network characteristics +- it is possible to add a section about "subnets" + +Here after, an "SDNC preload" example that can be use for Network +instantiation. + +:: + + curl -X POST \ + http://sdnc.api.simpledemo.onap.org:30202/restconf/operations/VNF-API:preload-network-topology-operation \ + -H 'Accept: application/json' \ + -H 'Authorization: Basic YWRtaW46S3A4Yko0U1hzek0wV1hsaGFrM2VIbGNzZTJnQXc4NHZhb0dHbUp2VXkyVQ==' \ + -H 'Content-Type: application/json' \ + -H 'X-FromAppId: API client' \ + -H 'X-TransactionId: 0a3f6713-ba96-4971-a6f8-c2da85a3176e' \ + -H 'cache-control: no-cache' \ + -d '{ + "input": { + "request-information": { + "request-id": "postman001", + "notification-url": "http://so.onap.org", + "order-number": "postman001", + "request-sub-action": "SUPP", + "request-action": "PreloadNetworkRequest", + "source": "postman", + "order-version": "1.0" + }, + "network-topology-information": { + "network-policy": [], + "route-table-reference": [], + "vpn-bindings": [], + "network-topology-identifier": { + "network-role": "integration_test_net", + "network-technology": "neutron", + "service-type": "Service-model-with-VNF-and-Virtual-Link", + "network-name": "my-network-instance-001", + "network-type": "Generic NeutronNet" + }, + "provider-network-information": { + "is-external-network": "false", + "is-provider-network": "false", + "is-shared-network": "false" + }, + "subnets": [ + { + "subnet-name": "my-sub_network-instance-001", + "subnet-role": "OAM", + "start-address": "192.168.90.0", + "cidr-mask": "24", + "ip-version": "4", + "dhcp-enabled": "Y", + "dhcp-start-address": "", + "dhcp-end-address": "", + "gateway-address": "192.168.90.1", + "host-routes":[] + } + ] + }, + "sdnc-request-header": { + "svc-action": "reserve", + "svc-notification-url": "http://so.onap.org", + "svc-request-id": "postman001" + } + } + } + ' + +Once the "SDNC preload" is completed, send it to SDNC using any Rest API Tool. + +Then, continue on VID and complete the fields indicated by the red star +and click "Confirm". + +Warning : be very careful to use exactly the same network instance name +on this screen and in the "SDNC preload" + +Wait for success and close the popup screen. + +The following screen should appear: + +.. figure:: images/create-network-instance-alacarte-after-instantiated.png + :align: center + +At that point, the Network and subnets are now instantiated +in the cloud platform. + +Also, all those network information are available in ONAP AAI, +under the terminology +"l3-network", with the "neutron-network-id" and the "neutron-subnet-id" +provided by +the openstack platform. + + +Deleting Network, VF module, VNF, Service +----------------------------------------- + +To delete a service instance using VID, it is necessary to delete objects +in the following sequence: + +- delete VF module(s) +- delete VNF instance(s) +- delete Network(s) +- delete service instance + +To proceed those deletion, from VID Home screen + +- search for existing service instance +- edit/view the service instance you want to delete +- click on red button with white cross and confirm for each object diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 8161f2931..03f2a6edf 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -8,9 +8,21 @@ Version: El-Alto (5.0.x) **Resolved Issues** + - `↗ <https://jira.onap.org/browse/VID-520>`_ Remove "Dissociate" button for Macro-orchestrated PNF resources + - `↗ <https://jira.onap.org/browse/VID-517>`_ Added liquidBase for follow changes in DB + - `↗ <https://jira.onap.org/browse/VID-488>`_ Added "Report" popup for common diagnosable cases + - `↗ <https://jira.onap.org/browse/VID-358>`_ vid-mariadb-galera runs in high-availability mode + **Security Notes** +*Fixed Security Issues* + + - `↗ <https://jira.onap.org/browse/OJSI-119>`_ Closed plain-text HTTP endpoint, port 30238 + +*Known Security Issues* + + Version: 4.3.2 diff --git a/epsdk-app-onap/src/main/java/org/onap/portalapp/conf/ExternalAppConfig.java b/epsdk-app-onap/src/main/java/org/onap/portalapp/conf/ExternalAppConfig.java index b4dcd346a..d9b0f092e 100644 --- a/epsdk-app-onap/src/main/java/org/onap/portalapp/conf/ExternalAppConfig.java +++ b/epsdk-app-onap/src/main/java/org/onap/portalapp/conf/ExternalAppConfig.java @@ -37,6 +37,8 @@ */ package org.onap.portalapp.conf; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; + import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; @@ -50,6 +52,7 @@ import org.onap.portalsdk.core.objectcache.AbstractCacheManager; import org.onap.portalsdk.core.service.DataAccessService; import org.onap.portalsdk.core.util.CacheManager; import org.onap.portalsdk.core.util.SystemProperties; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -164,8 +167,15 @@ public class ExternalAppConfig extends AppConfig implements Configurable { } @Bean - public LoginStrategy loginStrategy() { - return new LoginStrategyImpl(); + public LoginStrategy loginStrategy(@Value("${login.strategy.classname:}") String classname) throws ReflectiveOperationException { + return isNotEmpty(classname) ? + newLoginStrategyInstance(classname) : new LoginStrategyImpl(); + } + + private LoginStrategy newLoginStrategyInstance(String loginStrategyClassname) throws ReflectiveOperationException { + return (LoginStrategy) Class.forName(loginStrategyClassname) + .getConstructor() + .newInstance(); } @Bean diff --git a/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties b/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties index 4d54d8eb5..a11007f4b 100755 --- a/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties +++ b/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties @@ -147,6 +147,9 @@ vid.truststore.passwd.x=OBF:1dx01j0e1hs01t981mis1dws156s1ojc1qjc1zsx1pw31qob1qr7 mso.dme2.client.timeout=30000 mso.dme2.client.read.timeout=120000 +scheduler.user.name=test1 +scheduler.password=test2 + scheduler.create.new.vnf.change.instance=/v1/ChangeManagement/schedules/ scheduler.get.time.slots=/v1/ChangeManagement/schedules/ scheduler.server.url=http://localhost:1080/scheduler diff --git a/epsdk-app-onap/src/test/java/org/onap/portalapp/conf/ExternalAppConfigTest.java b/epsdk-app-onap/src/test/java/org/onap/portalapp/conf/ExternalAppConfigTest.java index 1bdf46325..f06526860 100644 --- a/epsdk-app-onap/src/test/java/org/onap/portalapp/conf/ExternalAppConfigTest.java +++ b/epsdk-app-onap/src/test/java/org/onap/portalapp/conf/ExternalAppConfigTest.java @@ -37,18 +37,23 @@ */ package org.onap.portalapp.conf; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.Assert; import org.junit.Test; +import org.onap.portalapp.login.LoginStrategyImpl; import org.onap.portalapp.scheduler.RegistryAdapter; import org.onap.portalsdk.core.auth.LoginStrategy; +import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; import org.onap.portalsdk.core.service.DataAccessService; -import org.springframework.jdbc.datasource.init.DataSourceInitializer; -import org.springframework.jdbc.datasource.init.DatabasePopulator; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; +import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; public class ExternalAppConfigTest { @@ -112,12 +117,39 @@ public class ExternalAppConfigTest { } @Test - public void testLoginStrategy() throws Exception { - ExternalAppConfig testSubject; - LoginStrategy result; + public void loginStrategy_givenEmptyString_yieldDefault() throws Exception { + assertThat(new ExternalAppConfig().loginStrategy(""), + is(instanceOf(LoginStrategyImpl.class))); + } - // default test - testSubject = createTestSubject(); - result = testSubject.loginStrategy(); + @Test + public void loginStrategy_givenNullString_yieldDefault() throws Exception { + assertThat(new ExternalAppConfig().loginStrategy(null), + is(instanceOf(LoginStrategyImpl.class))); + } + + public static class DummyLoginStrategy extends LoginStrategy { + @Override + public ModelAndView doLogin(HttpServletRequest request, HttpServletResponse response) { + return null; + } + + @Override + public String getUserId(HttpServletRequest request) { + return null; + } + } + + @Test + public void loginStrategy_givenClassname_yieldClassInstance() throws Exception { + assertThat( + new ExternalAppConfig().loginStrategy("org.onap.portalapp.conf.ExternalAppConfigTest$DummyLoginStrategy"), + is(instanceOf(DummyLoginStrategy.class))); + } + + @Test(expected = ClassNotFoundException.class) + public void loginStrategy_givenMissingClassname_throwsException() throws Exception { + new ExternalAppConfig().loginStrategy("no.real.classname"); + Assert.fail("should throw"); } -}
\ No newline at end of file +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/ResponseWithRequestInfo.java b/vid-app-common/src/main/java/org/onap/vid/aai/ResponseWithRequestInfo.kt index 567099c81..aaa41c2d3 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/ResponseWithRequestInfo.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/ResponseWithRequestInfo.kt @@ -18,32 +18,17 @@ * ============LICENSE_END========================================================= */ -package org.onap.vid.aai; +package org.onap.vid.aai -import org.springframework.http.HttpMethod; +import io.joshworks.restclient.http.HttpResponse +import org.springframework.http.HttpMethod -import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response -public class ResponseWithRequestInfo { - private String requestUrl; - private HttpMethod requestHttpMethod; - private Response response; +open class BaseResponseWithRequestInfo(val requestUrl: String?, val requestHttpMethod: HttpMethod) - public ResponseWithRequestInfo(Response response, String requestUrl, HttpMethod requestHttpMethod) { - this.response = response; - this.requestUrl = requestUrl; - this.requestHttpMethod = requestHttpMethod; - } +class HttpResponseWithRequestInfo<T>(val response: HttpResponse<T>?, requestUrl: String?, requestHttpMethod: HttpMethod) : + BaseResponseWithRequestInfo(requestUrl, requestHttpMethod) - public String getRequestUrl() { - return requestUrl; - } - - public HttpMethod getRequestHttpMethod() { - return requestHttpMethod; - } - - public Response getResponse() { - return response; - } -} +class ResponseWithRequestInfo(val response: Response?, requestUrl: String?, requestHttpMethod: HttpMethod) : + BaseResponseWithRequestInfo(requestUrl, requestHttpMethod) diff --git a/vid-app-common/src/main/java/org/onap/vid/asdc/AsdcClient.java b/vid-app-common/src/main/java/org/onap/vid/asdc/AsdcClient.java index fc04080d9..44257a62e 100644 --- a/vid-app-common/src/main/java/org/onap/vid/asdc/AsdcClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/asdc/AsdcClient.java @@ -22,10 +22,11 @@ package org.onap.vid.asdc; import io.joshworks.restclient.http.HttpResponse; -import org.onap.vid.asdc.beans.Service; - +import java.io.InputStream; import java.nio.file.Path; import java.util.UUID; +import org.onap.vid.aai.HttpResponseWithRequestInfo; +import org.onap.vid.asdc.beans.Service; /** * The Interface AsdcClient. @@ -55,6 +56,8 @@ public interface AsdcClient { Path getServiceToscaModel(UUID uuid) throws AsdcCatalogException; + HttpResponseWithRequestInfo<InputStream> getServiceInputStream(UUID serviceUuid, boolean warpException); + HttpResponse<String> checkSDCConnectivity(); String getBaseUrl(); diff --git a/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java b/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java index a82110744..decf446d6 100644 --- a/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/asdc/rest/SdcRestClient.java @@ -20,11 +20,32 @@ package org.onap.vid.asdc.rest; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; +import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM; +import static org.onap.portalsdk.core.util.SystemProperties.APP_DISPLAY_NAME; +import static org.onap.vid.asdc.AsdcClient.URIS.METADATA_URL_TEMPLATE; +import static org.onap.vid.asdc.AsdcClient.URIS.TOSCA_MODEL_URL_TEMPLATE; +import static org.onap.vid.client.SyncRestClientInterface.HEADERS.AUTHORIZATION; +import static org.onap.vid.client.SyncRestClientInterface.HEADERS.CONTENT_TYPE; +import static org.onap.vid.client.SyncRestClientInterface.HEADERS.X_ECOMP_INSTANCE_ID; +import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; +import static org.onap.vid.utils.Logging.logRequest; + import com.att.eelf.configuration.EELFLogger; import com.google.common.collect.ImmutableMap; import io.joshworks.restclient.http.HttpResponse; import io.vavr.control.Try; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.asdc.AsdcCatalogException; import org.onap.vid.asdc.AsdcClient; import org.onap.vid.asdc.beans.Service; @@ -34,26 +55,6 @@ import org.onap.vid.properties.VidProperties; import org.onap.vid.utils.Logging; import org.springframework.http.HttpMethod; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.Collections; -import java.util.Map; -import java.util.UUID; - -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM; -import static org.onap.portalsdk.core.util.SystemProperties.APP_DISPLAY_NAME; -import static org.onap.vid.asdc.AsdcClient.URIS.METADATA_URL_TEMPLATE; -import static org.onap.vid.asdc.AsdcClient.URIS.TOSCA_MODEL_URL_TEMPLATE; -import static org.onap.vid.client.SyncRestClientInterface.HEADERS.AUTHORIZATION; -import static org.onap.vid.client.SyncRestClientInterface.HEADERS.CONTENT_TYPE; -import static org.onap.vid.client.SyncRestClientInterface.HEADERS.X_ECOMP_INSTANCE_ID; -import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; -import static org.onap.vid.utils.Logging.logRequest; - public class SdcRestClient implements AsdcClient { private String baseUrl; @@ -86,17 +87,28 @@ public class SdcRestClient implements AsdcClient { @Override public Path getServiceToscaModel(UUID uuid) throws AsdcCatalogException { - String finalUrl = String.format(TOSCA_MODEL_URL_TEMPLATE, baseUrl, path, uuid); - logRequest(LOGGER, HttpMethod.GET, finalUrl); - InputStream inputStream = Try - .of(() -> syncRestClient.getStream(finalUrl, prepareHeaders(auth, APPLICATION_OCTET_STREAM), Collections.emptyMap())) + .of(() -> getServiceInputStream(uuid, false)) .getOrElseThrow(AsdcCatalogException::new) + .getResponse() .getBody(); return createTmpFile(inputStream); } + @Override + public HttpResponseWithRequestInfo<InputStream> getServiceInputStream(UUID serviceUuid, boolean warpException) { + String finalUrl = String.format(TOSCA_MODEL_URL_TEMPLATE, baseUrl, path, serviceUuid); + logRequest(LOGGER, HttpMethod.GET, finalUrl); + try { + HttpResponse<InputStream> httpResponse = syncRestClient.getStream(finalUrl, prepareHeaders(auth, APPLICATION_OCTET_STREAM), Collections.emptyMap()); + return new HttpResponseWithRequestInfo<>(httpResponse, finalUrl, HttpMethod.GET); + } + catch (RuntimeException exception) { + throw warpException ? new ExceptionWithRequestInfo(HttpMethod.GET, finalUrl, exception) : exception; + } + } + @Override public HttpResponse<String> checkSDCConnectivity() { diff --git a/vid-app-common/src/main/java/org/onap/vid/changeManagement/UpdateRequestInfo.java b/vid-app-common/src/main/java/org/onap/vid/changeManagement/UpdateRequestInfo.java index ff8516ea5..dc6e56f4a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/changeManagement/UpdateRequestInfo.java +++ b/vid-app-common/src/main/java/org/onap/vid/changeManagement/UpdateRequestInfo.java @@ -3,6 +3,7 @@ * VID * ================================================================================ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2018 IBM. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +27,12 @@ import org.onap.vid.mso.model.RequestInfo; * Created by Oren on 9/5/17. */ public class UpdateRequestInfo { + + public String source; + + public Boolean suppressRollback; + + public String requestorId; public UpdateRequestInfo() { } @@ -36,11 +43,6 @@ public class UpdateRequestInfo { this.suppressRollback = requestInfo.getSuppressRollback(); this.source = requestInfo.getSource(); } - public String source; - - public Boolean suppressRollback; - - public String requestorId; - + } diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java index eee2acc51..2b3ad60ea 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java @@ -77,6 +77,7 @@ public class AaiController extends RestrictedBaseController { private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AaiController.class); private static final String FROM_APP_ID = "VidAaiController"; + private final ObjectMapper objectMapper = new ObjectMapper(); private AaiService aaiService; private AAIRestInterface aaiRestInterface; @@ -157,7 +158,7 @@ public class AaiController extends RestrictedBaseController { throws IOException { ResponseEntity<String> responseEntity; if (aaiResponseData.getHttpCode() == 200) { - responseEntity = new ResponseEntity<>(new ObjectMapper().writeValueAsString(aaiResponseData.getT()), + responseEntity = new ResponseEntity<>(objectMapper.writeValueAsString(aaiResponseData.getT()), HttpStatus.OK); } else { responseEntity = new ResponseEntity<>(aaiResponseData.getErrorMessage(), @@ -225,7 +226,6 @@ public class AaiController extends RestrictedBaseController { @RequestMapping(value = "/aai_get_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<String> getFullSubscriberList(HttpServletRequest request) throws IOException { - ObjectMapper objectMapper = new ObjectMapper(); ResponseEntity<String> responseEntity; RoleValidator roleValidator = RoleValidator.by(roleProvider.getUserRoles(request)); SubscriberFilteredResults subscriberList = aaiService.getFullSubscriberList(roleValidator); @@ -270,17 +270,14 @@ public class AaiController extends RestrictedBaseController { @RequestMapping(value = "/aai_sub_details/{subscriberId}", method = RequestMethod.GET) public ResponseEntity<String> getSubscriberDetails(HttpServletRequest request, @PathVariable("subscriberId") String subscriberId, @RequestParam(value="omitServiceInstances", required = false, defaultValue = "false") boolean omitServiceInstances) throws IOException { - ObjectMapper objectMapper = new ObjectMapper(); - ResponseEntity responseEntity; List<Role> roles = roleProvider.getUserRoles(request); RoleValidator roleValidator = RoleValidator.by(roles); - AaiResponse subscriberData = aaiService.getSubscriberData(subscriberId, roleValidator, featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH) && omitServiceInstances); - String httpMessage = subscriberData.getT() != null ? - objectMapper.writeValueAsString(subscriberData.getT()) : - subscriberData.getErrorMessage(); + AaiResponse subscriberData = aaiService.getSubscriberData(subscriberId, roleValidator, + featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH) && omitServiceInstances); + String httpMessage = subscriberData.getT() != null ? objectMapper.writeValueAsString(subscriberData.getT()) : subscriberData.getErrorMessage(); - responseEntity = new ResponseEntity<>(httpMessage, HttpStatus.valueOf(subscriberData.getHttpCode())); - return responseEntity; + return new ResponseEntity<>(httpMessage, + HttpStatus.valueOf(subscriberData.getHttpCode())); } @RequestMapping(value = "/search_service_instances", method = RequestMethod.GET) @@ -289,7 +286,6 @@ public class AaiController extends RestrictedBaseController { @RequestParam(value = "serviceInstanceIdentifier", required = false) String instanceIdentifier, @RequestParam(value = "project", required = false) List<String> projects, @RequestParam(value = "owningEntity", required = false) List<String> owningEntities) throws IOException { - ObjectMapper objectMapper = new ObjectMapper(); ResponseEntity responseEntity; List<Role> roles = roleProvider.getUserRoles(request); @@ -354,7 +350,6 @@ public class AaiController extends RestrictedBaseController { @RequestMapping(value = "/aai_get_network_collection_details/{serviceInstanceId}", method = RequestMethod.GET) public ResponseEntity<String> getNetworkCollectionDetails( @PathVariable("serviceInstanceId") String serviceInstanceId) throws IOException { - com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper(); AaiResponse<String> resp = aaiService.getNetworkCollectionDetails(serviceInstanceId); String httpMessage = resp.getT() != null ? @@ -367,7 +362,6 @@ public class AaiController extends RestrictedBaseController { public ResponseEntity<String> getInstanceGroupsByCloudRegion(@PathVariable("cloudOwner") String cloudOwner, @PathVariable("cloudRegionId") String cloudRegionId, @PathVariable("networkFunction") String networkFunction) throws IOException { - com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper(); AaiResponse<AaiGetInstanceGroupsByCloudRegion> resp = aaiService .getInstanceGroupsByCloudRegion(cloudOwner, cloudRegionId, networkFunction); @@ -424,7 +418,6 @@ public class AaiController extends RestrictedBaseController { ResponseEntity responseEntity; try { - ObjectMapper objectMapper = new ObjectMapper(); List<Role> roles = roleProvider.getUserRoles(request); RoleValidator roleValidator = RoleValidator.by(roles); AaiResponse<GetTenantsResponse[]> response = aaiService diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/MsoController.java b/vid-app-common/src/main/java/org/onap/vid/controller/MsoController.java index fc718f0d2..535c97ce7 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/MsoController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/MsoController.java @@ -302,7 +302,6 @@ public class MsoController extends RestrictedBaseController { * @throws Exception the exception */ @RequestMapping(value = "/mso_delete_vnf_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}", method = RequestMethod.POST) - public ResponseEntity<String> deleteVnf(@PathVariable("serviceInstanceId") String serviceInstanceId, @PathVariable("vnfInstanceId") String vnfInstanceId, HttpServletRequest request, @RequestBody RequestDetails msoRequest) { @@ -449,7 +448,6 @@ public class MsoController extends RestrictedBaseController { * @return the response entity * @throws Exception the exception */ - //mso_delete_vf_module/bc305d54-75b4-431b-adb2-eb6b9e546014/vnfs/fe9000-0009-9999/vfmodules/abeeee-abeeee-abeeee @RequestMapping(value = "/mso_delete_vfmodule_instance/{serviceInstanceId}/vnfs/{vnfInstanceId}/vfModules/{vfModuleId}", method = RequestMethod.POST) public ResponseEntity<String> deleteVfModule( @PathVariable("serviceInstanceId") String serviceInstanceId, diff --git a/vid-app-common/src/main/java/org/onap/vid/model/RequestReferencesContainer.java b/vid-app-common/src/main/java/org/onap/vid/model/RequestReferencesContainer.java index cc8fff614..cd6942ee8 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/RequestReferencesContainer.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/RequestReferencesContainer.java @@ -3,6 +3,7 @@ * VID * ================================================================================ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 IBM. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +34,11 @@ public class RequestReferencesContainer { @JsonIgnore private Map<String, Object> additionalProperties = new HashMap<>(); - + + public RequestReferencesContainer(@JsonProperty("requestReferences") RequestReferences requestReferences) { + this.requestReferences = requestReferences; + } + @JsonAnyGetter public Map<String, Object> getAdditionalProperties() { return this.additionalProperties; @@ -44,10 +49,6 @@ public class RequestReferencesContainer { this.additionalProperties.put(name, value); } - public RequestReferencesContainer(@JsonProperty("requestReferences") RequestReferences requestReferences) { - this.requestReferences = requestReferences; - } - public RequestReferences getRequestReferences() { return requestReferences; } diff --git a/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/RelatedVnf.java b/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/RelatedVnf.java index febd8e0fd..f5c1428fe 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/RelatedVnf.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/aaiTree/RelatedVnf.java @@ -3,6 +3,7 @@ * VID * ================================================================================ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 IBM. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +31,10 @@ public class RelatedVnf extends Node { private String serviceInstanceName; private String tenantName; + public RelatedVnf(AAITreeNode node) { + super(node); + } + public String getServiceInstanceId() { return serviceInstanceId; } @@ -54,10 +59,6 @@ public class RelatedVnf extends Node { this.tenantName = tenantName; } - public RelatedVnf(AAITreeNode node) { - super(node); - } - public static RelatedVnf from(AAITreeNode node) { RelatedVnf vnf = new RelatedVnf(node); if (node.getParent() != null && node.getParent().getType() == NodeType.SERVICE_INSTANCE) { diff --git a/vid-app-common/src/main/java/org/onap/vid/model/probes/HttpRequestMetadata.java b/vid-app-common/src/main/java/org/onap/vid/model/probes/HttpRequestMetadata.java index 1638a376c..984c0d766 100644 --- a/vid-app-common/src/main/java/org/onap/vid/model/probes/HttpRequestMetadata.java +++ b/vid-app-common/src/main/java/org/onap/vid/model/probes/HttpRequestMetadata.java @@ -21,17 +21,19 @@ package org.onap.vid.model.probes; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; + import com.google.common.base.MoreObjects; -import io.joshworks.restclient.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.aai.ResponseWithRequestInfo; import org.onap.vid.mso.RestObjectWithRequestInfo; import org.onap.vid.utils.Logging; import org.springframework.http.HttpMethod; -import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; - public class HttpRequestMetadata extends StatusMetadata { private final HttpMethod httpMethod; private final int httpCode; @@ -81,6 +83,20 @@ public class HttpRequestMetadata extends StatusMetadata { duration); } + public HttpRequestMetadata(HttpResponseWithRequestInfo response, String description, long duration, boolean readRawData) { + super(description, duration); + this.httpMethod = response.getRequestHttpMethod(); + this.url = response.getRequestUrl(); + this.httpCode = response.getResponse().getStatus(); + if (readRawData) { + try { + response.getResponse().getRawBody().reset(); + this.rawData = IOUtils.toString(response.getResponse().getRawBody(), StandardCharsets.UTF_8.name()); + } catch (Exception e) { + //Nothing to do here + } + } + } public HttpMethod getHttpMethod() { diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java b/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java index 9146e8f1b..4d0d4ee74 100644 --- a/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java @@ -60,6 +60,8 @@ import javax.ws.rs.BadRequestException; import org.apache.commons.collections4.ListUtils; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.changeManagement.ChangeManagementRequest; import org.onap.vid.changeManagement.RequestDetailsWrapper; import org.onap.vid.changeManagement.WorkflowRequestDetail; @@ -67,6 +69,7 @@ import org.onap.vid.controller.OperationalEnvironmentController; import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.vid.model.SOWorkflowList; import org.onap.vid.model.SoftDeleteRequest; +import org.onap.vid.model.probes.ErrorMetadata; import org.onap.vid.model.probes.ExternalComponentStatus; import org.onap.vid.model.probes.HttpRequestMetadata; import org.onap.vid.model.probes.StatusMetadata; @@ -84,8 +87,8 @@ import org.onap.vid.mso.rest.RequestList; import org.onap.vid.mso.rest.RequestWrapper; import org.onap.vid.mso.rest.Task; import org.onap.vid.mso.rest.TaskList; +import org.onap.vid.utils.Logging; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; public class MsoBusinessLogicImpl implements MsoBusinessLogic { @@ -383,12 +386,13 @@ public class MsoBusinessLogicImpl implements MsoBusinessLogic { } private List<RequestWrapper> getOrchestrationRequestsByFilter(String filterName, String filterValue) { + HttpResponseWithRequestInfo<String> msoResponseWrapper = getRawOrchestrationRequestsByFilter(filterName, filterValue); + return deserializeOrchestrationRequestsJson(msoResponseWrapper.getResponse().getBody()); + } + + private HttpResponseWithRequestInfo<String> getRawOrchestrationRequestsByFilter(String filterName, String filterValue) { String orchestrationReqPath = constructOrchestrationRequestFilter(filterName, filterValue); - RestObject<String> restObjStr = new RestObject<>(); - String str = new String(); - restObjStr.set(str); - MsoResponseWrapper msoResponseWrapper = msoClientInterface.getOrchestrationRequest(str, "", orchestrationReqPath, restObjStr, true); - return deserializeOrchestrationRequestsJson(msoResponseWrapper.getEntity()); + return msoClientInterface.getOrchestrationRequest(orchestrationReqPath, true); } private List<RequestWrapper> deserializeOrchestrationRequestsJson(String orchestrationRequestsJson) { @@ -837,22 +841,38 @@ public class MsoBusinessLogicImpl implements MsoBusinessLogic { @Override public ExternalComponentStatus probeComponent() { - String url = SystemProperties.getProperty( - MsoProperties.MSO_SERVER_URL) + "/" + SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS); - long startTime = System.currentTimeMillis(); - ExternalComponentStatus externalComponentStatus; - + final long startTime = System.currentTimeMillis(); + HttpResponseWithRequestInfo<String> responseWithRequestInfo = null; try { - String rawBody = objectMapper.writeValueAsString(getOrchestrationRequestsForDashboard()); - StatusMetadata statusMetadata=new HttpRequestMetadata(HttpMethod.GET,200,url,rawBody,"VID-SO",System.currentTimeMillis() - startTime); + responseWithRequestInfo = getRawOrchestrationRequestsByFilter("requestExecutionDate", "01-01-2100" ); + int httpCode = responseWithRequestInfo.getResponse().getStatus(); + boolean isAvailable = httpCode == 200 || httpCode == 202; + if (isAvailable) { + //make sure response can be parsed to RequestList.class + JACKSON_OBJECT_MAPPER.readValue(responseWithRequestInfo.getResponse().getBody(), RequestList.class); + } + + HttpRequestMetadata metadata = new HttpRequestMetadata(responseWithRequestInfo, + isAvailable ? "OK" : "MSO returned no orchestration requests", + System.currentTimeMillis() - startTime, true); + return new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, isAvailable, metadata); - externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, true, statusMetadata); + } catch (ExceptionWithRequestInfo e) { + long duration = System.currentTimeMillis() - startTime; + return new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, false, + new HttpRequestMetadata(e, duration)); } catch (Exception e) { - StatusMetadata statusMetadata = new HttpRequestMetadata(HttpMethod.GET, HttpStatus.INTERNAL_SERVER_ERROR.value(), url, "", e.getMessage(), System.currentTimeMillis() - startTime); - externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, false, statusMetadata); - } + StatusMetadata metadata; + long duration = System.currentTimeMillis() - startTime; - return externalComponentStatus; + if (responseWithRequestInfo == null) { + metadata = new ErrorMetadata(Logging.exceptionToDescription(e), duration); + } else { + metadata = new HttpRequestMetadata(responseWithRequestInfo, Logging.exceptionToDescription(e), duration, true); + } + + return new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, false, metadata); + } } private void validateUpdateVnfConfig(RequestDetails requestDetails) { diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java b/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java index 46bd2731d..d1cb3a37b 100644 --- a/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java +++ b/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java @@ -21,6 +21,7 @@ package org.onap.vid.mso; import io.joshworks.restclient.http.HttpResponse; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.changeManagement.RequestDetailsWrapper; import org.onap.vid.model.SOWorkflowList; import org.onap.vid.changeManagement.WorkflowRequestDetail; @@ -89,7 +90,7 @@ public interface MsoInterface { MsoResponseWrapper deleteNwInstance(RequestDetails requestDetails, String endpoint); - MsoResponseWrapper getOrchestrationRequest(String t, String sourceId, String endpoint, RestObject restObject, boolean warpException); + HttpResponseWithRequestInfo<String> getOrchestrationRequest(String endpoint, boolean warpException); MsoResponseWrapper getOrchestrationRequest(String endpoint); diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java b/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java index df8034b22..cc6d6123d 100644 --- a/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java +++ b/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java @@ -35,6 +35,7 @@ import org.apache.commons.codec.binary.Base64; import org.eclipse.jetty.util.security.Password; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.aai.util.HttpsAuthClient; import org.onap.vid.changeManagement.MsoRequestDetails; import org.onap.vid.changeManagement.RequestDetailsWrapper; @@ -51,6 +52,7 @@ import org.onap.vid.mso.RestMsoImplementation; import org.onap.vid.mso.RestObject; import org.onap.vid.utils.Logging; import org.onap.vid.utils.SystemPropertiesWrapper; +import org.springframework.http.HttpMethod; /** @@ -216,11 +218,11 @@ public class MsoRestClientNew extends RestMsoImplementation implements MsoInterf } @Override - public MsoResponseWrapper getOrchestrationRequest(String t, String sourceId, String endpoint, RestObject restObject, boolean warpException) { + public HttpResponseWithRequestInfo<String> getOrchestrationRequest(String endpoint, boolean warpException) { String path = baseUrl + endpoint; HttpResponse<String> response = client.get(path, commonHeaders, new HashMap<>(), String.class); - return MsoUtil.wrapResponse(response); + return new HttpResponseWithRequestInfo<>(response, path, HttpMethod.GET); } @Override diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/rest/TaskList.java b/vid-app-common/src/main/java/org/onap/vid/mso/rest/TaskList.java index 90e3a21e3..cfde4c954 100644 --- a/vid-app-common/src/main/java/org/onap/vid/mso/rest/TaskList.java +++ b/vid-app-common/src/main/java/org/onap/vid/mso/rest/TaskList.java @@ -3,6 +3,7 @@ * VID * ================================================================================ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 IBM. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +24,8 @@ package org.onap.vid.mso.rest; import java.util.List; public class TaskList { + + private List<Task> taskList; public List<Task> getTaskList() { return taskList; @@ -32,5 +35,4 @@ public class TaskList { this.taskList = taskList; } - private List<Task> taskList; } diff --git a/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java b/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java index 78b3e9709..001a8ae6d 100644 --- a/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java +++ b/vid-app-common/src/main/java/org/onap/vid/scheduler/SchedulerRestInterface.java @@ -21,6 +21,7 @@ package org.onap.vid.scheduler; import com.att.eelf.configuration.EELFLogger; +import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import io.joshworks.restclient.http.HttpResponse; @@ -43,6 +44,7 @@ import java.util.Collections; import java.util.Map; import java.util.function.Function; +import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY; @Service @@ -90,15 +92,20 @@ public class SchedulerRestInterface implements SchedulerRestInterfaceIfc { .putAll(commonHeaders) .put(REQUEST_ID_HEADER_KEY, Logging.extractOrGenerateRequestId()) .build(); - final HttpResponse<T> response = ((HttpResponse<T>) syncRestClient.get(url, requestHeaders, - Collections.emptyMap(), t.getClass())); + final HttpResponse<String> response = syncRestClient.get(url, requestHeaders, + Collections.emptyMap(), String.class); Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, response); status = response.getStatus(); restObject.setStatusCode(status); - + rawData = response.getBody(); + restObject.setRaw(rawData); if (status == 200) { - t = response.getBody(); - restObject.set(t); + if (t instanceof String) { + restObject.set((T)rawData); + } + else { + restObject.set(JACKSON_OBJECT_MAPPER.readValue(rawData, (Class<T>)t.getClass())); + } logger.debug(EELFLoggerDelegate.debugLogger, "<== " + methodName + SUCCESSFUL_API_MESSAGE); logger.info(EELFLoggerDelegate.errorLogger, "<== " + methodName + SUCCESSFUL_API_MESSAGE); } else { @@ -106,7 +113,7 @@ public class SchedulerRestInterface implements SchedulerRestInterfaceIfc { } return new RestObjectWithRequestInfo<>(HttpMethod.GET, url, restObject, status, rawData); } - catch (RuntimeException e) { + catch (Exception e) { throw new ExceptionWithRequestInfo(HttpMethod.GET, url, rawData, status, e); } } diff --git a/vid-app-common/src/main/java/org/onap/vid/services/VidServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/VidServiceImpl.java index 9d6f74def..a5988a156 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/VidServiceImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/VidServiceImpl.java @@ -20,12 +20,22 @@ */ package org.onap.vid.services; +import static org.onap.vid.model.probes.ExternalComponentStatus.Component.SDC; +import static org.onap.vid.properties.Features.FLAG_SERVICE_MODEL_CACHE; + import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import io.joshworks.restclient.http.HttpResponse; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException; +import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.asdc.AsdcCatalogException; import org.onap.vid.asdc.AsdcClient; import org.onap.vid.asdc.beans.Service; @@ -34,20 +44,16 @@ import org.onap.vid.asdc.parser.ToscaParserImpl; import org.onap.vid.asdc.parser.ToscaParserImpl2; import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.vid.model.ServiceModel; +import org.onap.vid.model.probes.ErrorMetadata; import org.onap.vid.model.probes.ExternalComponentStatus; import org.onap.vid.model.probes.HttpRequestMetadata; +import org.onap.vid.model.probes.StatusMetadata; +import org.onap.vid.properties.VidProperties; import org.onap.vid.utils.Logging; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.togglz.core.manager.FeatureManager; -import java.nio.file.Path; -import java.util.UUID; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import static org.onap.vid.properties.Features.FLAG_SERVICE_MODEL_CACHE; - /** * The Class VidController. */ @@ -150,6 +156,20 @@ public class VidServiceImpl implements VidService { @Override public ExternalComponentStatus probeComponent() { + UUID modelUUID; + try { + modelUUID = UUID.fromString(VidProperties.getPropertyWithDefault( + VidProperties.PROBE_SDC_MODEL_UUID,"")); + } + //in case of no such PROBE_SDC_MODEL_UUID property or non uuid there we check only sdc connectivity + catch (Exception e) { + return probeComponentBySdcConnectivity(); + } + + return probeSdcByGettingModel(modelUUID); + } + + public ExternalComponentStatus probeComponentBySdcConnectivity() { long startTime = System.currentTimeMillis(); ExternalComponentStatus externalComponentStatus; try { @@ -158,10 +178,49 @@ public class VidServiceImpl implements VidService { System.currentTimeMillis() - startTime); externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.SDC, stringHttpResponse.isSuccessful(), httpRequestMetadata); } catch (Exception e) { - HttpRequestMetadata httpRequestMetadata = new HttpRequestMetadata(HttpMethod.GET, 0, - AsdcClient.URIS.HEALTH_CHECK_ENDPOINT, "", Logging.exceptionToDescription(e), System.currentTimeMillis() - startTime); - externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.SDC, false, httpRequestMetadata); + ErrorMetadata errorMetadata = new ErrorMetadata(Logging.exceptionToDescription(e), System.currentTimeMillis() - startTime); + externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.SDC, false, errorMetadata); } return externalComponentStatus; } + + protected ExternalComponentStatus probeSdcByGettingModel(UUID modelUUID) { + final long startTime = System.currentTimeMillis(); + + HttpResponseWithRequestInfo<InputStream> response = null; + try { + response = asdcClient.getServiceInputStream(modelUUID, true); + int responseStatusCode = response.getResponse().getStatus(); + + if (responseStatusCode == 404) { + return errorStatus(response, startTime, "model " + modelUUID + " not found in SDC" + + " (consider updating vid probe configuration '" + VidProperties.PROBE_SDC_MODEL_UUID + "')"); + } else if (responseStatusCode >= 400) { + return errorStatus(response, startTime, "error while retrieving model " + modelUUID + " from SDC"); + } else { + InputStream inputStreamEntity = response.getResponse().getRawBody();//validate we can read the input steam from the response + if (inputStreamEntity.read() <= 0) { + return errorStatus(response, startTime, "error reading model " + modelUUID + " from SDC"); + } else { + // RESPONSE IS SUCCESS + return new ExternalComponentStatus(SDC, true, + new HttpRequestMetadata(response, "OK", startTime, false)); + } + } + } catch (ExceptionWithRequestInfo e) { + return new ExternalComponentStatus(SDC, false, + new HttpRequestMetadata(e, System.currentTimeMillis() - startTime)); + } catch (Exception e) { + return errorStatus(response, startTime, Logging.exceptionToDescription(e)); + } + } + + private ExternalComponentStatus errorStatus(HttpResponseWithRequestInfo<InputStream> response, long startTime, String description) { + final long duration = System.currentTimeMillis() - startTime; + StatusMetadata statusMetadata = (response == null) ? + new ErrorMetadata(description, duration) : + new HttpRequestMetadata(response, description, duration, true); + + return new ExternalComponentStatus(SDC, false, statusMetadata); + } } diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java index df7f20e49..71478fcf1 100644 --- a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java +++ b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java @@ -119,7 +119,7 @@ public class Logging { response.bufferEntity(); logger.debug("Received {} {} Status: {} . Body: {}", method.name(), url, response.getStatus(), response.readEntity(entityClass)); } - catch (ProcessingException | IllegalStateException e) { + catch (Exception e) { logger.debug("Received {} {} Status: {} . Failed to read response as {}", method.name(), url, response.getStatus(), entityClass.getName()); } } @@ -128,7 +128,7 @@ public class Logging { try { logger.debug("Received {} {} Status: {} . Body: {}", method.name(), url, response.getStatus(), response.getBody()); } - catch (ProcessingException | IllegalStateException e) { + catch (Exception e) { logger.debug("Received {} {} Status: {} . Failed to read response", method.name(), url, response.getStatus()); } } diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js index e66b8ff6c..bf3d54af0 100755 --- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js @@ -55,7 +55,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", componentId: COMPONENT.VNF,
callbackFunction: callbackFunction
});
- }
+ };
$scope.popup = new Object();
@@ -85,18 +85,18 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", $scope.getServiceTypes = function (globalCustomerId) {
DataService.setGlobalCustomerId(globalCustomerId);
- DataService.setServiceIdList($scope.customerList)
+ DataService.setServiceIdList($scope.customerList);
if (globalCustomerId !== "" && globalCustomerId !== undefined) {
window.location.href = COMPONENT.SERVICE_TYPE_LIST_PATH + $scope.serviceTypeList;
}
- }
+ };
$scope.refreshServiceTypes = function (globalCustomerId) {
DataService.setGlobalCustomerId(globalCustomerId);
$scope.getServiceTypesList();
- }
+ };
$scope.subId = "";
$scope.createSubscriberName = "";
@@ -138,7 +138,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", $scope.subList = [];
$scope.getAaiServiceModels = function (selectedServicetype, subName) {
DataService.setGlobalCustomerId(selectedServicetype);
- DataService.setServiceIdList($scope.serviceTypeList)
+ DataService.setServiceIdList($scope.serviceTypeList);
DataService.setSubscriberName(subName);
DataService.setSubscribers($scope.custSubList);
@@ -347,12 +347,12 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", callbackFunction: function (response) {
}
});
- }
+ };
$scope.cancelCreateSIType = function () {
window.location.href = COMPONENT.SERVICE_MODLES_INSTANCES_SUBSCRIBERS_PATH;
- }
+ };
$scope.fetchServices = function () {
var serviceIdList = [];
@@ -395,12 +395,12 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", $scope.errorMsg = FIELD.ERROR.AAI_FETCHING_CUST_DATA + response.status;
$scope.errorDetails = response.data;
});
- }
+ };
$scope.getPermitted = function (item) {
return item.isPermitted || item[FIELD.ID.IS_PERMITTED];
- }
+ };
$scope.getSubDetails = function () {
@@ -482,7 +482,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", $scope.enableCloseButton(false);
$scope.resetProgress();
$scope.setProgress(2); // Show "a little" progress
- }
+ };
function getRelatedInstanceGroupsByVnfId(genericVnf) {
var model = vidService.getModel();
@@ -503,7 +503,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", )
}
}
- })
+ });
}
}
@@ -516,7 +516,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", return resolveIfIsPermitted()
.then(function() {
return getAsdcModelByVersionId(modelVersionId);
- })
+ });
}
}
@@ -689,7 +689,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", // the response is erroneous
console.log("aaiSubscriber getAsdcModel BAD RESPONSE");
errorCallback(response);
- return $q.reject()
+ return $q.reject();
}
}, errorCallback);
@@ -706,9 +706,9 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", if (item[FIELD.ID.SERVICE_INSTANCES] != null) {
item[FIELD.ID.SERVICE_INSTANCES][FIELD.ID.SERVICE_INSTANCE].forEach(function (service) {
if (service[FIELD.ID.SERVICE_INSTANCE_ID] === serviceId) {
- orchStatus = service['orchestration-status']
+ orchStatus = service['orchestration-status'];
}
- })
+ });
}
});
return orchStatus;
@@ -722,7 +722,7 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", }, function (response) {
//TODO
});
- }
+ };
$scope.isConfigurationDataAvailiable = function (configuration) {
$log.debug(configuration);
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.controller.js index a7f7e9128..b6725b124 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.controller.js +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.controller.js @@ -30,7 +30,7 @@ var vfModuleActionModalController = function(COMPONENT, FIELD, $scope, $uibModal $scope.vfModuleName = vfModule.name; $scope.volumeGroups = vfModule.volumeGroups; $scope.lcpAndTenant = null; - $scope.regionSelection = {lcpRegion: null, legacyRegion: null, tenant: null}; + $scope.regionSelection = {optionId: null, legacyRegion: null, tenant: null}; $scope.lcpRegionList = null; $scope.isHomingData = false; $scope.megaRegion = ['AAIAIC25']; @@ -60,12 +60,12 @@ var vfModuleActionModalController = function(COMPONENT, FIELD, $scope, $uibModal .then(function (res) { if (res && res.data) { $scope.regionSelection = { - lcpRegion: (res.data[COMPONENT.CLOUD_REGION_ID]) ? res.data[COMPONENT.CLOUD_REGION_ID] : null, + optionId: (res.data[COMPONENT.CLOUD_REGION_ID]) ? res.data[COMPONENT.CLOUD_REGION_ID] : null, legacyRegion: null, tenant: (res.data[COMPONENT.TENANT_ID]) ? res.data[COMPONENT.TENANT_ID] : null }; - $scope.isHomingData = $scope.regionSelection.lcpRegion !== null && res.data.tenant !== null; - $scope.isHomingData = $scope.isHomingData && (($scope.megaRegion).indexOf($scope.regionSelection.lcpRegion) === -1); + $scope.isHomingData = $scope.regionSelection.optionId !== null && res.data.tenant !== null; + $scope.isHomingData = $scope.isHomingData && !$scope.selectedLcpRegionIsMegaRegion(); } if (!$scope.isHomingData) { @@ -75,11 +75,11 @@ var vfModuleActionModalController = function(COMPONENT, FIELD, $scope, $uibModal .catch(function (error) { getLcpCloudRegionTenantList(); }); - }; + } function getLcpRegionId() { if(_.isEmpty($scope.regionSelection.legacyRegion)) { - return $scope.regionSelection.lcpRegion + return DataService.getCloudOwnerAndLcpCloudRegionFromOptionId($scope.regionSelection.optionId).cloudRegionId; } return $scope.regionSelection.legacyRegion; } @@ -144,6 +144,12 @@ var vfModuleActionModalController = function(COMPONENT, FIELD, $scope, $uibModal return AaiService.removeVendorFromCloudOwner(cloudOwner) }; + $scope.selectedLcpRegionIsMegaRegion = function() { + let cloudRegionId = + DataService.getCloudOwnerAndLcpCloudRegionFromOptionId($scope.regionSelection.optionId).cloudRegionId; + return ($scope.megaRegion).indexOf(cloudRegionId) > -1 + }; + $scope.cancel = function() { $uibModalInstance.dismiss('cancel'); }; diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.html index 3fbe07e83..944352403 100644 --- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.html +++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/vf-module-homing-data-action/vf-module-homing-data-action.html @@ -55,7 +55,7 @@ <div class="lcp-region field"> <label>LCP Region</label> <select name="lcp-region" required class="form-item wide" - data-tests-id="lcpRegion" data-ng-model="regionSelection.lcpRegion" + data-tests-id="lcpRegion" data-ng-model="regionSelection.optionId" data-ng-change="regionSelection.tenant = null; regionSelection.legacyRegion = null;"> <option class="lcp-region-placeholder" value="" selected>Select LCP Region</option> <option ng-repeat="option in lcpRegionList" value="{{option.cloudRegionOptionId}}" @@ -69,7 +69,7 @@ </select> </div> - <div class="legacy-region field" data-ng-if="(megaRegion).indexOf(regionSelection.lcpRegion) > -1"> + <div class="legacy-region field" data-ng-if="selectedLcpRegionIsMegaRegion()"> <label>Legacy Region</label> <input type="text" data-tests-id="lcpRegionText" required data-ng-model="regionSelection.legacyRegion" placeholder="Enter legacy region"> @@ -81,7 +81,7 @@ data-tests-id="tenant" data-ng-model="regionSelection.tenant"> <option class="tenant-placeholder" value="" selected>Select Tenant Name</option> <option ng-repeat="option in lcpAndTenant" class="tenantOption" value="{{option.tenantId}}" - data-ng-if="option.isPermitted && option.cloudRegionOptionId === regionSelection.lcpRegion">{{option.tenantName}} + data-ng-if="option.isPermitted && option.cloudRegionOptionId === regionSelection.optionId">{{option.tenantName}} </option> </select> </div> diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java index b2d8e85fa..9793862ca 100644 --- a/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java @@ -56,6 +56,7 @@ import java.net.URI; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Map; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Stream; diff --git a/vid-app-common/src/main/java/org/onap/vid/asdc/local/LocalAsdcClient.java b/vid-app-common/src/test/java/org/onap/vid/asdc/local/LocalAsdcClient.java index ce1bbe930..2f5853e47 100644 --- a/vid-app-common/src/main/java/org/onap/vid/asdc/local/LocalAsdcClient.java +++ b/vid-app-common/src/test/java/org/onap/vid/asdc/local/LocalAsdcClient.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.joshworks.restclient.http.HttpResponse; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.file.Path; @@ -34,6 +35,7 @@ import java.nio.file.Paths; import java.util.UUID; import org.json.JSONArray; import org.json.JSONObject; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.asdc.AsdcCatalogException; import org.onap.vid.asdc.AsdcClient; import org.onap.vid.asdc.beans.Service; @@ -162,6 +164,10 @@ public class LocalAsdcClient implements AsdcClient { return HttpResponse.fallback(""); } + @Override + public HttpResponseWithRequestInfo<InputStream> getServiceInputStream(UUID serviceUuid, boolean warpException) { + return null; + } @Override public String getBaseUrl(){ diff --git a/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java b/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java index 126f30067..589874d2a 100644 --- a/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/asdc/rest/SdcRestClientITTest.java @@ -85,7 +85,7 @@ public class SdcRestClientITTest { String expectedEndpoint = String.format("/sdc/v1/catalog/services/%s/toscaModel", uuid); stubServer.prepareGetCall( - expectedEndpoint, stringContent("sampleFileContent"), "sampleFileContent", ok(), "application/octet-stream"); + expectedEndpoint, stringContent("sampleFileContent"), ok(), "application/octet-stream"); Path serviceToscaModel = sdcRestClient.getServiceToscaModel(uuid); diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java index 2377c8055..b51bbdc31 100644 --- a/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java @@ -21,14 +21,11 @@ package org.onap.vid.controller; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.booleanThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -40,16 +37,14 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; -import java.io.IOException; import java.util.Map; import java.util.UUID; -import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; import org.onap.vid.aai.AaiResponse; import org.onap.vid.aai.AaiResponseTranslator.PortMirroringConfigData; @@ -62,13 +57,13 @@ import org.onap.vid.aai.model.PortDetailsTranslator.PortDetails; import org.onap.vid.aai.model.PortDetailsTranslator.PortDetailsError; import org.onap.vid.aai.model.PortDetailsTranslator.PortDetailsOk; import org.onap.vid.aai.util.AAIRestInterface; -import org.onap.vid.properties.Features; -import org.onap.vid.roles.Role; import org.onap.vid.model.VersionByInvariantIdsRequest; +import org.onap.vid.properties.Features; import org.onap.vid.roles.RoleProvider; -import org.onap.vid.roles.RoleValidator; +import org.onap.vid.roles.RoleValidatorByRoles; import org.onap.vid.services.AaiService; import org.onap.vid.utils.SystemPropertiesWrapper; +import org.onap.vid.utils.Unchecked; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -83,7 +78,7 @@ public class AaiControllerTest { private final ObjectMapper objectMapper = new ObjectMapper(); @Mock private AaiService aaiService; - @Mock + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private AAIRestInterface aaiRestInterface; @Mock private RoleProvider roleProvider; @@ -98,11 +93,140 @@ public class AaiControllerTest { @Before public void setUp() { - aaiController = new AaiController(aaiService, aaiRestInterface, roleProvider, systemPropertiesWrapper, featureManager); + aaiController = new AaiController(aaiService, aaiRestInterface, roleProvider, systemPropertiesWrapper, + featureManager); mockMvc = MockMvcBuilders.standaloneSetup(aaiController).build(); } @Test + public void getAicZoneForPnf_shouldReturnOKResponse() throws Exception { + String globalCustomerId = "testCustomerId"; + String serviceType = "testServiceType"; + String serviceId = "testServiceId"; + String expectedResponseBody = "OK_RESPONSE"; + AaiResponse<String> aaiResponse = new AaiResponse<>(expectedResponseBody, null, HttpStatus.OK.value()); + given(aaiService.getAicZoneForPnf(globalCustomerId, serviceType, serviceId)).willReturn(aaiResponse); + + mockMvc.perform( + get("/aai_get_aic_zone_for_pnf/{globalCustomerId}/{serviceType}/{serviceId}", globalCustomerId, serviceType, + serviceId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(expectedResponseBody))); + } + + @Test + public void getInstanceGroupsByVnfInstanceId_shouldReturnOKResponse() throws Exception { + String vnfInstanceId = "testVndInstanceId"; + String expectedResponseBody = "OK_RESPONSE"; + AaiResponse<String> aaiResponse = new AaiResponse<>(expectedResponseBody, null, HttpStatus.OK.value()); + given(aaiService.getInstanceGroupsByVnfInstanceId(vnfInstanceId)).willReturn(aaiResponse); + + mockMvc.perform(get("/aai_get_instance_groups_by_vnf_instance_id/{vnfInstanceId}", vnfInstanceId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(expectedResponseBody))); + } + + @Test + public void doGetServiceInstance_shouldFetchServiceInstance_byServiceInstanceId() throws Exception { + String serviceInstanceId = "testServiceInstanceId"; + String serviceInstanceType = "Service Instance Id"; + String expectedResponseBody = "OK_RESPONSE"; + Response response = mock(Response.class); + given(response.readEntity(String.class)).willReturn(expectedResponseBody); + given(response.getStatus()).willReturn(HttpStatus.OK.value()); + + given(aaiRestInterface.RestGet(eq("VidAaiController"), anyString(), eq(Unchecked.toURI( + "search/nodes-query?search-node-type=service-instance&filter=service-instance-id:EQUALS:" + + serviceInstanceId)), + eq(false)).getResponse()).willReturn(response); + + mockMvc + .perform(get("/aai_get_service_instance/{service-instance-id}/{service-instance-type}", serviceInstanceId, + serviceInstanceType) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponseBody)); + } + + @Test + public void doGetServiceInstance_shouldFetchServiceInstance_byServiceInstanceName() throws Exception { + String serviceInstanceId = "testServiceInstanceId"; + String serviceInstanceType = "testServiceInstanceType"; + String expectedResponseBody = "OK_RESPONSE"; + Response response = mock(Response.class); + given(response.readEntity(String.class)).willReturn(expectedResponseBody); + given(response.getStatus()).willReturn(HttpStatus.OK.value()); + + given(aaiRestInterface.RestGet(eq("VidAaiController"), anyString(), eq(Unchecked.toURI( + "search/nodes-query?search-node-type=service-instance&filter=service-instance-name:EQUALS:" + + serviceInstanceId)), + eq(false)).getResponse()).willReturn(response); + + mockMvc + .perform(get("/aai_get_service_instance/{service-instance-id}/{service-instance-type}", serviceInstanceId, + serviceInstanceType) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponseBody)); + } + + @Test + public void doGetServices_shouldReturnOkResponse() throws Exception { + String globalCustomerId = "testGlobalCustomerId"; + String serviceSubscriptionId = "testServiceSubscriptionId"; + String expectedResponseBody = "OK_RESPONSE"; + Response response = mock(Response.class); + given(response.readEntity(String.class)).willReturn(expectedResponseBody); + given(response.getStatus()).willReturn(HttpStatus.OK.value()); + + given(aaiRestInterface.RestGet( + eq("VidAaiController"), + anyString(), + eq(Unchecked.toURI( + "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + + serviceSubscriptionId + "?depth=0")), + eq(false)).getResponse()).willReturn(response); + + mockMvc + .perform( + get("/aai_get_service_subscription/{global-customer-id}/{service-subscription-id}", globalCustomerId, + serviceSubscriptionId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponseBody)); + } + + @Test + public void doGetServices_shouldReturnInternalServerError_forEmptyResponse() throws Exception { + String globalCustomerId = "testGlobalCustomerId"; + String serviceSubscriptionId = "testServiceSubscriptionId"; + String expectedResponseBody = "Failed to fetch data from A&AI, check server logs for details."; + given(aaiRestInterface.RestGet( + eq("VidAaiController"), + anyString(), + eq(Unchecked.toURI( + "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + + serviceSubscriptionId + "?depth=0")), + eq(false)).getResponse()).willReturn(null); + + mockMvc + .perform( + get("/aai_get_service_subscription/{global-customer-id}/{service-subscription-id}", globalCustomerId, + serviceSubscriptionId) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isInternalServerError()) + .andExpect(content().string(expectedResponseBody)); + } + + @Test public void getPortMirroringConfigData_givenIds_shouldReturnConfigDataMappedById() throws Exception { PortMirroringConfigDataOk okConfigData = new PortMirroringConfigDataOk("foo"); PortMirroringConfigDataError errorConfigData = new PortMirroringConfigDataError("bar", "{ baz: qux }"); @@ -259,7 +383,7 @@ public class AaiControllerTest { mockMvc.perform( post("/aai_get_version_by_invariant_id") - .content(new ObjectMapper().writeValueAsString(request)) + .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) @@ -267,40 +391,71 @@ public class AaiControllerTest { } @Test - public void getSubscriberDetailsOmitServiceInstances_reduceDepthEnabledAndOmitQueryParam() throws IOException { - getSubscriberDetailsOmitServiceInstances("some subscriber id", - true, true, true); + public void getSubscriberDetails_shouldOmitServiceInstancesFromSubscriberData_whenFeatureEnabled_andOmitFlagIsTrue() + throws Exception { + boolean isFeatureActive = true; + boolean omitServiceInstances = true; + + String subscriberId = "subscriberId"; + String okResponseBody = "OK_RESPONSE"; + AaiResponse<String> aaiResponse = new AaiResponse<>(okResponseBody, "", HttpStatus.OK.value()); + given(featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH)).willReturn(isFeatureActive); + given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidatorByRoles.class), + eq(isFeatureActive && omitServiceInstances))) + .willReturn(aaiResponse); + + mockMvc.perform( + get("/aai_sub_details/{subscriberId}", subscriberId) + .param("omitServiceInstances", Boolean.toString(omitServiceInstances)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(okResponseBody))); } @Test - public void getSubscriberDetailsOmitServiceInstances_reduceDepthDisabledAndOmitQueryParam() throws IOException { - getSubscriberDetailsOmitServiceInstances("another-subscriber-id-123", - false, true, false); + public void getSubscriberDetails_shouldIncludeServiceInstancesFromSubscriberData_whenFeatureEnabled_andOmitFlagIsFalse() + throws Exception { + boolean isFeatureActive = true; + boolean omitServiceInstances = false; + + getSubscriberDetails_assertServiceInstancesInclusion(isFeatureActive, omitServiceInstances); } @Test - public void getSubscriberDetailsOmitServiceInstances_reduceDepthDisabled() throws IOException { - getSubscriberDetailsOmitServiceInstances("123-456-789-123-345-567-6", - false, false, false); + public void getSubscriberDetails_shouldIncludeServiceInstancesFromSubscriberData_whenFeatureDisabled_andOmitFlagIsTrue() + throws Exception { + boolean isFeatureActive = false; + boolean omitServiceInstances = true; + + getSubscriberDetails_assertServiceInstancesInclusion(isFeatureActive, omitServiceInstances); } @Test - public void getSubscriberDetailsOmitServiceInstances_reduceDepthEnabled() throws IOException { - getSubscriberDetailsOmitServiceInstances("0000000000000000000000000", - true, false, false); + public void getSubscriberDetails_shouldIncludeServiceInstancesFromSubscriberData_whenFeatureDisabled_andOmitFlagIsFalse() + throws Exception { + boolean isFeatureActive = false; + boolean omitServiceInstances = false; + getSubscriberDetails_assertServiceInstancesInclusion(isFeatureActive, omitServiceInstances); } - private void getSubscriberDetailsOmitServiceInstances(String subscriberId, boolean isFlag1906AaiSubDetailsReduceDepthEnabled, - boolean omitServiceInstancesQueryParam, boolean omitServiceInstancesExpectedGetSubscriberDataParam) throws IOException { - when(featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH)).thenReturn(isFlag1906AaiSubDetailsReduceDepthEnabled); - HttpServletRequest request = mock(HttpServletRequest.class); - when(roleProvider.getUserRoles(request)).thenReturn(ImmutableList.of(mock(Role.class), mock(Role.class))); - AaiResponse subscriberData = mock(AaiResponse.class); - when(subscriberData.getT()).thenReturn(null); - when(subscriberData.getHttpCode()).thenReturn(200); - when(aaiService.getSubscriberData(any(), any(), anyBoolean())).thenReturn(subscriberData); - aaiController.getSubscriberDetails(request, subscriberId, omitServiceInstancesQueryParam); - verify(aaiService).getSubscriberData(argThat(subscriberId::equals), any(RoleValidator.class), booleanThat(b -> omitServiceInstancesExpectedGetSubscriberDataParam == b)); + private void getSubscriberDetails_assertServiceInstancesInclusion(boolean isFeatureActive, + boolean omitServiceInstances) throws Exception { + String subscriberId = "subscriberId"; + String okResponseBody = "OK_RESPONSE"; + AaiResponse<String> aaiResponse = new AaiResponse<>(okResponseBody, "", HttpStatus.OK.value()); + given(featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH)).willReturn(isFeatureActive); + given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidatorByRoles.class), + eq(isFeatureActive && omitServiceInstances))) + .willReturn(aaiResponse); + + mockMvc.perform( + get("/aai_sub_details/{subscriberId}", subscriberId) + .param("omitServiceInstances", Boolean.toString(omitServiceInstances)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(objectMapper.writeValueAsString(okResponseBody))); } } diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/MsoControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/MsoControllerTest.java index a1b45590c..a2f86f437 100644 --- a/vid-app-common/src/test/java/org/onap/vid/controller/MsoControllerTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/controller/MsoControllerTest.java @@ -20,6 +20,7 @@ package org.onap.vid.controller; +import static java.lang.String.format; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -44,11 +45,14 @@ import org.jeasy.random.randomizers.misc.BooleanRandomizer; import org.jeasy.random.randomizers.text.StringRandomizer; import org.junit.Before; import org.junit.Test; +import org.onap.vid.model.RequestReferencesContainer; import org.onap.vid.mso.MsoBusinessLogic; import org.onap.vid.mso.MsoResponseWrapper; +import org.onap.vid.mso.RestObject; import org.onap.vid.mso.rest.MsoRestClientNew; import org.onap.vid.mso.rest.Request; import org.onap.vid.mso.rest.RequestDetails; +import org.onap.vid.mso.rest.RequestDetailsWrapper; import org.onap.vid.mso.rest.Task; import org.onap.vid.services.CloudOwnerService; import org.springframework.test.web.servlet.MockMvc; @@ -80,6 +84,27 @@ public class MsoControllerTest { } @Test + public void shouldGetOrchestrationRequest() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String requestId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + + MsoResponseWrapper expectedResponse = new MsoResponseWrapper(200, "test"); + given(msoBusinessLogic + .getOrchestrationRequest(requestId)) + .willReturn(expectedResponse); + + // when & then + mockMvc.perform(get(format("/mso/mso_get_orch_req/%s", requestId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(asJson(expectedResponse))); + + then(cloudService).shouldHaveZeroInteractions(); + } + + @Test public void shouldDelegateNewServiceInstantiation() throws Exception { // given RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); @@ -100,6 +125,28 @@ public class MsoControllerTest { } @Test + public void shouldCreateVolumeInstance() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String vnfInstanceId = "fe9000-0009-9999"; + + MsoResponseWrapper expectedResponse = new MsoResponseWrapper(200, "test"); + given(msoBusinessLogic + .createVolumeGroupInstance(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(vnfInstanceId))) + .willReturn(expectedResponse); + + // when & then + mockMvc.perform(post(format("/mso/mso_create_volumegroup_instance/%s/vnfs/%s", serviceInstanceId, vnfInstanceId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(asJson(expectedResponse))); + + then(cloudService).should(only()).enrichRequestWithCloudOwner(objectEqualTo(requestDetails)); + } + + @Test public void shouldReturnOrchestrationRequestsForDashboard() throws Exception { // given List<Request> orchestrationRequests = modelGenerator @@ -195,6 +242,135 @@ public class MsoControllerTest { } @Test + public void shouldDeleteVfModuleInstance() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String vnfInstanceId = "fe9000-0009-9999"; + String vfModuleId = "abeeee-abeeee-abeeee"; + + MsoResponseWrapper wrapper = mock(MsoResponseWrapper.class); + given(wrapper.getResponse()).willReturn("some response"); + given(msoBusinessLogic.deleteVfModule(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(vnfInstanceId), eq(vfModuleId))).willReturn(wrapper); + + // when & then + mockMvc.perform(post(format("/mso/mso_delete_vfmodule_instance/%s/vnfs/%s/vfModules/%s", serviceInstanceId, vnfInstanceId, vfModuleId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("some response")); + + then(cloudService).should(only()).enrichRequestWithCloudOwner(objectEqualTo(requestDetails)); + } + + @Test + public void shouldDeleteVolumeGroup() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String vnfInstanceId = "fe9000-0009-9999"; + String volumeGroupId = "abeeee-abeeee-abeeee"; + + MsoResponseWrapper wrapper = mock(MsoResponseWrapper.class); + given(wrapper.getResponse()).willReturn("some response"); + given(msoBusinessLogic.deleteVolumeGroupInstance(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(vnfInstanceId), eq(volumeGroupId))).willReturn(wrapper); + + // when & then + mockMvc.perform(post(format("/mso/mso_delete_volumegroup_instance/%s/vnfs/%s/volumeGroups/%s", serviceInstanceId, vnfInstanceId, volumeGroupId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("some response")); + + then(cloudService).should(only()).enrichRequestWithCloudOwner(objectEqualTo(requestDetails)); + } + + @Test + public void shouldDeleteInstance() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String networkInstanceId = "fe9000-0009-9999"; + + MsoResponseWrapper wrapper = mock(MsoResponseWrapper.class); + given(wrapper.getResponse()).willReturn("some response"); + given(msoBusinessLogic.deleteNwInstance(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(networkInstanceId))).willReturn(wrapper); + + // when & then + mockMvc.perform(post(format("/mso/mso_delete_nw_instance/%s/networks/%s", serviceInstanceId, networkInstanceId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("some response")); + + then(cloudService).should(only()).enrichRequestWithCloudOwner(objectEqualTo(requestDetails)); + } + + @Test + public void shouldDeleteServiceInstance() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String serviceStatus = "ACTIVE"; + + MsoResponseWrapper wrapper = mock(MsoResponseWrapper.class); + given(wrapper.getResponse()).willReturn("some response"); + given(msoBusinessLogic.deleteSvcInstance(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(serviceStatus))).willReturn(wrapper); + + // when & then + mockMvc.perform(post(format("/mso/mso_delete_svc_instance/%s", serviceInstanceId)) + .param("serviceStatus", serviceStatus) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("some response")); + + then(cloudService).shouldHaveZeroInteractions(); + } + + @Test + public void shouldDeleteVnf() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String vnfInstanceId = "fe9000-0009-9999"; + + MsoResponseWrapper wrapper = mock(MsoResponseWrapper.class); + given(wrapper.getResponse()).willReturn("some response"); + given(msoBusinessLogic.deleteVnf(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(vnfInstanceId))).willReturn(wrapper); + + // when & then + mockMvc.perform(post(format("/mso/mso_delete_vnf_instance/%s/vnfs/%s", serviceInstanceId, vnfInstanceId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("some response")); + + then(cloudService).should(only()).enrichRequestWithCloudOwner(objectEqualTo(requestDetails)); + } + + @Test + public void shouldDeleteConfiguration() throws Exception { + // given + RequestDetailsWrapper requestDetails = modelGenerator.nextObject(RequestDetailsWrapper.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + String configurationId = "fe9000-0009-9999"; + + MsoResponseWrapper wrapper = mock(MsoResponseWrapper.class); + given(wrapper.getResponse()).willReturn("some response"); + given(msoBusinessLogic.deleteConfiguration(objectEqualTo(requestDetails), eq(serviceInstanceId), eq(configurationId))).willReturn(wrapper); + + // when & then + mockMvc.perform(post(format("/mso/mso_delete_configuration/%s/configurations/%s", serviceInstanceId, configurationId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("some response")); + + then(cloudService).should(only()).enrichRequestWithCloudOwner(objectEqualTo(requestDetails.getRequestDetails())); + } + + @Test public void shouldDelegateNewInstanceCreation() throws Exception { // given RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); @@ -234,6 +410,32 @@ public class MsoControllerTest { then(cloudService).shouldHaveZeroInteractions(); } + @Test + public void shouldActivateFabricConfiguration() throws Exception { + // given + RequestDetails requestDetails = modelGenerator.nextObject(RequestDetails.class); + String serviceInstanceId = "bc305d54-75b4-431b-adb2-eb6b9e546014"; + + String path = "/mso/path"; + given(msoBusinessLogic.getActivateFabricConfigurationPath(eq(serviceInstanceId))).willReturn(path); + + RestObject<RequestReferencesContainer> response = new RestObject<>(); + response.set(mock(RequestReferencesContainer.class)); + response.setRaw("some response"); + response.setStatusCode(200); + + given(msoRestClient.PostForObject(objectEqualTo(requestDetails), eq(path), eq(RequestReferencesContainer.class))).willReturn(response); + + // when & then + mockMvc.perform(post(format("/mso/mso_activate_fabric_configuration/%s", serviceInstanceId)) + .content(asJson(requestDetails)) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string("{\"status\":200,\"entity\":{}}")); + + then(cloudService).shouldHaveZeroInteractions(); + } + private <T> String asJson(T value) { try { return objectMapper.writeValueAsString(value); diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java index 4ddbc0f41..ffabc18a2 100644 --- a/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java @@ -25,7 +25,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.tuple; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -37,19 +42,20 @@ import static org.mockito.ArgumentMatchers.isA; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.onap.vid.controller.MsoController.CONFIGURATION_ID; import static org.onap.vid.controller.MsoController.REQUEST_TYPE; import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID; import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID; +import static org.onap.vid.model.probes.ExternalComponentStatus.Component.MSO; import static org.onap.vid.mso.MsoBusinessLogicImpl.validateEndpointPath; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; -import com.google.gson.Gson; import io.joshworks.restclient.http.HttpResponse; import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -60,19 +66,26 @@ import java.util.UUID; import java.util.stream.Collectors; import javax.ws.rs.BadRequestException; import org.apache.commons.io.IOUtils; +import org.apache.http.HttpException; +import org.hamcrest.Matcher; +import org.hamcrest.MatcherAssert; import org.jetbrains.annotations.NotNull; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.hamcrest.MockitoHamcrest; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.changeManagement.ChangeManagementRequest; import org.onap.vid.changeManagement.WorkflowRequestDetail; import org.onap.vid.controller.OperationalEnvironmentController; import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.vid.model.SOWorkflowList; import org.onap.vid.model.SoftDeleteRequest; +import org.onap.vid.model.probes.ErrorMetadata; import org.onap.vid.model.probes.ExternalComponentStatus; +import org.onap.vid.model.probes.HttpRequestMetadata; import org.onap.vid.mso.model.CloudConfiguration; import org.onap.vid.mso.model.ModelInfo; import org.onap.vid.mso.model.OperationalEnvironmentActivateInfo; @@ -83,9 +96,8 @@ import org.onap.vid.mso.rest.OperationalEnvironment.OperationEnvironmentRequestD import org.onap.vid.mso.rest.Request; import org.onap.vid.mso.rest.RequestDetails; import org.onap.vid.mso.rest.RequestDetailsWrapper; -import org.onap.vid.mso.rest.RequestList; -import org.onap.vid.mso.rest.RequestWrapper; import org.onap.vid.mso.rest.Task; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; @@ -97,6 +109,7 @@ import org.testng.annotations.Test; public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests { private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final String MY_PRETTY_URL = "my pretty url"; @Mock private MsoInterface msoInterface; @@ -496,12 +509,8 @@ public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests { String vnfModelTypeOrchestrationRequests = getFileContentAsString("mso_model_info_sample_response.json"); String scaleOutActionOrchestrationRequests = getFileContentAsString("mso_action_scaleout_sample_response.json"); - MsoResponseWrapper msoResponseWrapperMock = mock(MsoResponseWrapper.class); - given(msoInterface - .getOrchestrationRequest(any(String.class), any(String.class), any(String.class), - any(RestObject.class), anyBoolean())) - .willReturn(msoResponseWrapperMock); - given(msoResponseWrapperMock.getEntity()) + HttpResponse<String> httpResponse = mockForGetOrchestrationRequest(); + given(httpResponse.getBody()) .willReturn(vnfModelTypeOrchestrationRequests, scaleOutActionOrchestrationRequests); //when @@ -523,13 +532,7 @@ public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests { //given String vnfModelTypeOrchestrationRequests = getFileContentAsString("mso_model_info_sample_wrong_response.json"); - MsoResponseWrapper msoResponseWrapperMock = mock(MsoResponseWrapper.class); - given(msoInterface - .getOrchestrationRequest(any(String.class), any(String.class), any(String.class), - any(RestObject.class), anyBoolean())) - .willReturn(msoResponseWrapperMock); - given(msoResponseWrapperMock.getEntity()) - .willReturn(vnfModelTypeOrchestrationRequests); + mockForGetOrchestrationRequest(200, vnfModelTypeOrchestrationRequests); //when msoBusinessLogic.getOrchestrationRequestsForDashboard(); @@ -1318,9 +1321,15 @@ public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests { @Test public void probeShouldReturnOrchestrationRequestsAndConnectionStatus(){ - MsoResponseWrapper wrapper = getMsoResponseWrapper(); - given(msoInterface.getOrchestrationRequest(anyString(),anyString(), - anyString(),any(RestObject.class),anyBoolean())).willReturn(wrapper); + String body = + "{" + + " \"requestList\":" + + " [{" + + " \"request\": {}" + + " }" + + " ]" + + "}"; + mockForGetOrchestrationRequest(200, body); ExternalComponentStatus externalComponentStatus = msoBusinessLogic.probeComponent(); @@ -1328,18 +1337,6 @@ public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests { assertThat(externalComponentStatus.getComponent()).isEqualTo(ExternalComponentStatus.Component.MSO); } - @NotNull - private MsoResponseWrapper getMsoResponseWrapper() { - MsoResponseWrapper wrapper=new MsoResponseWrapper(); - RequestWrapper requestWrapper = new RequestWrapper(); - requestWrapper.setRequest(new Request()); - RequestList requestList = new RequestList(); - List<RequestWrapper> response = Lists.newArrayList(requestWrapper); - requestList.setRequestList(response); - wrapper.setEntity(new Gson().toJson(requestList)); - return wrapper; - } - private WorkflowRequestDetail createWorkflowRequestDetail() { WorkflowRequestDetail workflowRequestDetail = new WorkflowRequestDetail(); org.onap.vid.changeManagement.RequestParameters requestParameters = new org.onap.vid.changeManagement.RequestParameters(); @@ -1429,5 +1426,193 @@ public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests { super(testException); } } + + //you need to add mocks to httpResponse + private HttpResponse<String> mockForGetOrchestrationRequest() { + + HttpResponse<String> httpResponse = mock(HttpResponse.class); + HttpResponseWithRequestInfo<String> httpResponseWithRequestInfo = new HttpResponseWithRequestInfo<>(httpResponse, MY_PRETTY_URL, HttpMethod.GET); + when(msoInterface.getOrchestrationRequest(any(String.class),anyBoolean())) + .thenReturn(httpResponseWithRequestInfo); + return httpResponse; + } + + private HttpResponse<String> mockForGetOrchestrationRequest(int statusCode, String body) { + + HttpResponse<String> httpResponse = mockForGetOrchestrationRequest(); + when(httpResponse.getStatus()).thenReturn(statusCode); + when(httpResponse.getBody()).thenReturn(body); + try { + when(httpResponse.getRawBody()).thenReturn(IOUtils.toInputStream(body, StandardCharsets.UTF_8.name())); + } catch (IOException e) { + throw new RuntimeException(e); + } + return httpResponse; + } + + @Test + public void probeComponent_verifyGoodRequest(){ + String responseString = "" + + "{ " + + " \"requestList\": [{ " + + " \"request\": { " + + " \"requestDetails\": { " + + " \"cloudConfiguration\": { " + + " \"lcpCloudRegionId\": \"hvf6\", " + + " \"cloudOwner\": \"irma-aic\", " + + " \"tenantId\": \"ffdf52b5e5104b0e8f329b0b1637ee2e\" " + + " }, " + + " \"modelInfo\": { " + + " \"modelCustomizationName\": \"VSP1710PID298109_vWINIFRED 0\", " + + " \"modelCustomizationId\": \"24d43fdb-9aa6-4287-a68e-1e702ea89d13\", " + + " \"modelInvariantId\": \"e7961100-cde6-4b5a-bcda-b8945086950a\", " + + " \"modelVersionId\": \"959a7ba0-89ee-4984-9af6-65d5bdda4b0e\", " + + " \"modelName\": \"VSP1710PID298109_vWINIFRED\", " + + " \"modelType\": \"vnf\", " + + " \"modelVersion\": \"1.0\" " + + " }, " + + " \"relatedModelList\": [{ " + + " \"relatedInstance\": { " + + " \"instanceId\": \"6dd0f8de-93c7-48a2-914b-1a8d58e0eb48\", " + + " \"modelInfo\": { " + + " \"modelInvariantId\": \"57e00952-0af7-4f0f-b19a-408a6f73c8df\", " + + " \"modelType\": \"service\", " + + " \"modelName\": \"ServicevWINIFREDPID298109\", " + + " \"modelVersion\": \"1.0\", " + + " \"modelVersionId\": \"fe6985cd-ea33-3346-ac12-ab121484a3fe\" " + + " } " + + " } " + + " } " + + " ], " + + " \"requestInfo\": { " + + " \"source\": \"VID\", " + + " \"suppressRollback\": false, " + + " \"requestorId\": \"ds828e\" " + + " }, " + + " \"requestParameters\": { " + + " \"userParams\": [ " + + " ], " + + " \"aLaCarte\": false, " + + " \"usePreload\": true, " + + " \"rebuildVolumeGroups\": false, " + + " \"autoBuildVfModules\": false, " + + " \"cascadeDelete\": false " + + " }, " + + " \"relatedInstanceList\": [{ " + + " \"relatedInstance\": { " + + " \"instanceId\": \"6dd0f8de-93c7-48a2-914b-1a8d58e0eb48\", " + + " \"modelInfo\": { " + + " \"modelInvariantId\": \"57e00952-0af7-4f0f-b19a-408a6f73c8df\", " + + " \"modelType\": \"service\", " + + " \"modelName\": \"ServicevWINIFREDPID298109\", " + + " \"modelVersion\": \"1.0\", " + + " \"modelVersionId\": \"fe6985cd-ea33-3346-ac12-ab121484a3fe\" " + + " } " + + " } " + + " } " + + " ] " + + " }, " + + " \"requestId\": \"d352c70d-5ef8-4977-9ea8-4c8cbe860422\", " + + " \"requestScope\": \"vnf\", " + + " \"requestStatus\": { " + + " \"percentProgress\": 100.0, " + + " \"requestState\": \"Some Unknown Value\", " + + " \"statusMessage\": \"Update Is In Progress\", " + + " \"finishTime\": \"Fri, 08 Sep 2017 19:34:33 GMT\" " + + " }, " + + " \"requestType\": \"updateInstance\", " + + " \"startTime\": \"<IN_PROGRESS_DATE>\", " + + " \"instanceReferences\": { " + + " \"serviceInstanceId\": \"6dd0f8de-93c7-48a2-914b-1a8d58e0eb48\", " + + " \"vnfInstanceId\": \"7c00cc1e-6425-4fc3-afc3-0289db288d4c\", " + + " \"requestorId\": \"ds828e\" " + + " } " + + " } " + + " } " + + " ] " + + "} "; + + mockForGetOrchestrationRequest(200, responseString); + + final ExternalComponentStatus msoStatus = msoBusinessLogic.probeComponent(); + + assertMsoStatus(msoStatus, true); + assertMetadata(msoStatus, 200, startsWith(responseString.substring(0, 400)), MY_PRETTY_URL, equalTo("OK")); + } + + @Test + public void probeComponent_response200OkButEmptyPayload_shouldDescribeCorrectly() { + String responseString = "" + + "{ " + + " \"requestList\": []" + + "}"; + + mockForGetOrchestrationRequest(200, responseString); + + final ExternalComponentStatus msoStatus = msoBusinessLogic.probeComponent(); + + assertMsoStatus(msoStatus, true); + + assertMetadata(msoStatus, 200, equalTo(responseString), MY_PRETTY_URL, containsString("OK")); + } + + @Test + public void probeComponent_response200OkButInvalidPayload_shouldDescribeCorrectly() { + String responseString = "this payload is an invalid json"; + + mockForGetOrchestrationRequest(200, responseString); + + final ExternalComponentStatus msoStatus = msoBusinessLogic.probeComponent(); + + assertMsoStatus(msoStatus, false); + + assertMetadata(msoStatus, 200, equalTo(responseString), MY_PRETTY_URL, containsString("JsonParseException: Unrecognized token")); + } + + @Test + public void probeComponent_verifyResponse406() { + String responseString = "my raw data"; + + when(msoInterface.getOrchestrationRequest(any(), eq(true))).thenThrow( + new ExceptionWithRequestInfo(HttpMethod.GET, MY_PRETTY_URL, responseString, 406, + new GenericUncheckedException( + new HttpException("Simulating as 406 was returned (200 or 202 expected)")))); + + final ExternalComponentStatus msoStatus = msoBusinessLogic.probeComponent(); + + assertMsoStatus(msoStatus, false); + + assertMetadata(msoStatus, 406, equalTo(responseString), MY_PRETTY_URL, containsString("HttpException: Simulating as 406 was returned")); + } + + + @Test + public void probeComponent_throwNullPointerException_resultIsWithErrorMetadata() { + when(msoInterface.getOrchestrationRequest(any(), eq(true))).thenThrow(new NullPointerException()); + + final ExternalComponentStatus msoStatus = msoBusinessLogic.probeComponent(); + + MatcherAssert.assertThat(msoStatus.isAvailable(), is(false)); + MatcherAssert.assertThat(msoStatus.getComponent(), is(MSO)); + MatcherAssert.assertThat(msoStatus.getMetadata(), instanceOf(ErrorMetadata.class)); + + final ErrorMetadata metadata = ((ErrorMetadata) msoStatus.getMetadata()); + org.junit.Assert.assertThat(metadata.getDescription(), containsString("NullPointerException")); + } + + private void assertMsoStatus(ExternalComponentStatus msoStatus, boolean isAvailable) { + MatcherAssert.assertThat(msoStatus.isAvailable(), is(isAvailable)); + MatcherAssert.assertThat(msoStatus.getComponent(), is(MSO)); + MatcherAssert.assertThat(msoStatus.getMetadata(), instanceOf(HttpRequestMetadata.class)); + } + + private void assertMetadata(ExternalComponentStatus msoStatus, int httpCode, Matcher<String> rawData, String url, Matcher<String> descriptionMatcher) { + final HttpRequestMetadata metadata = ((HttpRequestMetadata) msoStatus.getMetadata()); + org.junit.Assert.assertThat(metadata.getHttpMethod(), equalTo(HttpMethod.GET)); + org.junit.Assert.assertThat(metadata.getHttpCode(), equalTo(httpCode)); + org.junit.Assert.assertThat(metadata.getUrl(), equalTo(url)); + org.junit.Assert.assertThat(metadata.getRawData(), rawData); + org.junit.Assert.assertThat(metadata.getDescription(), descriptionMatcher); + } } diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java index 6cf7d487e..c47e7ce4e 100644 --- a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java @@ -46,6 +46,7 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.client.SyncRestClient; import org.onap.vid.controller.MsoController; import org.onap.vid.controller.WebConfig; @@ -325,23 +326,6 @@ public class MsoRestClientNewTest { } @Test - public void testGetOrchestrationRequestsForDashboard() throws Exception { - MsoRestClientNew testSubject; - String t = ""; - String sourceId = ""; - String endpoint = ""; - RestObject restObject = null; - MsoResponseWrapper result; - - // default test - try { - testSubject = createTestSubject(); - result = testSubject.getOrchestrationRequest(t, sourceId, endpoint, restObject, true); - } catch (Exception e) { - } - } - - @Test public void testCompleteManualTask() throws Exception { MsoRestClientNew testSubject; RequestDetails requestDetails = null; diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTest.java index e4e699d55..c91e88be7 100644 --- a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTest.java @@ -38,6 +38,7 @@ import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.mockito.Mock; import org.onap.portalsdk.core.util.SystemProperties; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.changeManagement.RequestDetailsWrapper; import org.onap.vid.changeManagement.WorkflowRequestDetail; import org.onap.vid.client.SyncRestClient; @@ -50,6 +51,7 @@ import org.onap.vid.mso.MsoUtil; import org.onap.vid.mso.RestObject; import org.onap.vid.mso.model.RequestReferences; import org.onap.vid.utils.SystemPropertiesWrapper; +import org.springframework.http.HttpMethod; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.web.WebAppConfiguration; import org.testng.annotations.BeforeClass; @@ -375,17 +377,15 @@ public class MsoRestClientTest { @Test public void shouldProperlyGetOrchestrationRequest() { - // given - RestObject restObject = generateMockMsoRestObject(); - String endpoint = "testEndpoint"; HttpResponse<String> httpResponse = HttpResponse.fallback("testOkResponse"); - MsoResponseWrapper expectedResponse = MsoUtil.wrapResponse(httpResponse); + String expectedPath = baseUrl+endpoint; + HttpResponseWithRequestInfo<String> expectedResponse = new HttpResponseWithRequestInfo<>(httpResponse, expectedPath, HttpMethod.GET); - when( client.get( eq(baseUrl+endpoint),anyMap(),anyMap(),eq(String.class) ) ).thenReturn(httpResponse); + when( client.get( eq(expectedPath), anyMap(), anyMap(), eq(String.class) )).thenReturn(httpResponse); // when - MsoResponseWrapper response = restClient.getOrchestrationRequest(null,null,endpoint,restObject,true); + HttpResponseWithRequestInfo<String> response = restClient.getOrchestrationRequest(endpoint, true); // then assertThat(response).isEqualToComparingFieldByField(expectedResponse); diff --git a/vid-app-common/src/test/java/org/onap/vid/services/VidServiceImplTest.java b/vid-app-common/src/test/java/org/onap/vid/services/VidServiceImplTest.java index ff6b7f0b1..65712b423 100644 --- a/vid-app-common/src/test/java/org/onap/vid/services/VidServiceImplTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/services/VidServiceImplTest.java @@ -21,27 +21,44 @@ package org.onap.vid.services; import static java.util.stream.Collectors.toMap; +import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.IsSame.sameInstance; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.testng.AssertJUnit.assertTrue; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.joshworks.restclient.http.HttpResponse; +import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.util.Map; import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.ws.rs.ProcessingException; +import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.commons.lang3.tuple.Triple; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException; +import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.HttpResponseWithRequestInfo; import org.onap.vid.asdc.AsdcCatalogException; import org.onap.vid.asdc.AsdcClient; import org.onap.vid.asdc.beans.Service; @@ -50,7 +67,10 @@ import org.onap.vid.model.ServiceModel; import org.onap.vid.model.probes.ExternalComponentStatus; import org.onap.vid.model.probes.HttpRequestMetadata; import org.onap.vid.properties.Features; +import org.onap.vid.testUtils.TestUtils; +import org.springframework.http.HttpMethod; import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.togglz.core.manager.FeatureManager; @@ -151,10 +171,7 @@ public class VidServiceImplTest { @Test public void shouldCheckConnectionToSdc() { - when(asdcClientMock.checkSDCConnectivity()).thenReturn(httpResponse); - when(httpResponse.isSuccessful()).thenReturn(true); - when(httpResponse.getBody()).thenReturn("sampleBody"); - + mockGoodSdcConnectivityResponse(); ExternalComponentStatus externalComponentStatus = vidService.probeComponent(); @@ -164,6 +181,12 @@ public class VidServiceImplTest { assertThat(metadata.getRawData(), is("sampleBody")); } + private void mockGoodSdcConnectivityResponse() { + when(asdcClientMock.checkSDCConnectivity()).thenReturn(httpResponse); + when(httpResponse.isSuccessful()).thenReturn(true); + when(httpResponse.getBody()).thenReturn("sampleBody"); + } + @Test public void shouldProperlyHandleNotWorkingSDCConnection(){ when(asdcClientMock.checkSDCConnectivity()).thenThrow(new RuntimeException("not working")); @@ -173,5 +196,129 @@ public class VidServiceImplTest { assertThat(externalComponentStatus.isAvailable(), is(false)); assertThat(externalComponentStatus.getMetadata().getDescription(),containsString("not working")); } + + @Test + public void shouldNotProbeBySdcConnectionIfProbeUuidConfigured() throws Exception { + TestUtils.testWithSystemProperty( + "probe.sdc.model.uuid", + UUID.randomUUID().toString(), + ()->{ + mockGoodSdcConnectivityResponse(); //no mocking for probeSdcByGettingModel + ExternalComponentStatus externalComponentStatus = vidService.probeComponent(); + assertThat(externalComponentStatus.isAvailable(), is(false)); + } + ); + } + + + @Test + public void givenProbeUUID_whenAsdcClientReturnNormal_thenProbeComponentReturnAvailableAnswer() throws Exception { + + final UUID uuidForProbe = UUID.randomUUID(); + final HttpResponse<InputStream> mockResponse = mock(HttpResponse.class); + responseSetupper(mockResponse, 200, new ByteArrayInputStream(RandomUtils.nextBytes(66000))); + when(asdcClientMock.getServiceInputStream(eq(uuidForProbe), eq(true))).thenReturn( + new HttpResponseWithRequestInfo(mockResponse, "my pretty url", HttpMethod.GET) + ); + + TestUtils.testWithSystemProperty( + "probe.sdc.model.uuid", + uuidForProbe.toString(), + ()-> { + + ExternalComponentStatus sdcComponentStatus = vidService.probeComponent(); + assertTrue(sdcComponentStatus.isAvailable()); + assertThat(sdcComponentStatus.getComponent(), is(ExternalComponentStatus.Component.SDC)); + assertThat(sdcComponentStatus.getMetadata().getDescription(), equalTo("OK")); + assertThat(sdcComponentStatus.getMetadata(), instanceOf(HttpRequestMetadata.class)); + + HttpRequestMetadata componentStatusMetadata = ((HttpRequestMetadata) sdcComponentStatus.getMetadata()); + assertThat(componentStatusMetadata.getHttpMethod(), equalTo(HttpMethod.GET)); + assertThat(componentStatusMetadata.getHttpCode(), equalTo(200)); + assertThat(componentStatusMetadata.getUrl(), equalTo("my pretty url")); + } + ); + } + + private static void responseSetupper(HttpResponse<InputStream> r, Integer httpCode, InputStream body) { + when(r.getStatus()).thenReturn(httpCode); + when(r.getRawBody()).thenReturn(body); + } + + @DataProvider + public static Object[][] executionResults() { + final BiConsumer<AsdcClient, HttpResponse<InputStream>> defaultClientSetup = (c, r) -> + when(c.getServiceInputStream(any(), eq(true))).thenReturn(new HttpResponseWithRequestInfo(r, "foo url", HttpMethod.GET)); + + final ByteArrayInputStream defaultResponseBody = new ByteArrayInputStream(RandomUtils.nextBytes(200)); + + return Stream.<Triple<HttpRequestMetadata, BiConsumer<AsdcClient, HttpResponse<InputStream>>, Consumer<HttpResponse<InputStream>>>>of( + + Triple.of( + new HttpRequestMetadata(null, 200, null, null, "IllegalStateException", 0), + defaultClientSetup, + r -> { + when(r.getStatus()).thenReturn(200); + when(r.getRawBody()).thenThrow(new IllegalStateException("good news for people who love bad news")); + } + ), + + Triple.of( + new HttpRequestMetadata(null, 200, null, null, "error reading model", 0), + defaultClientSetup, + r -> responseSetupper(r, 200, new ByteArrayInputStream(new byte[0])) + ), +// + Triple.of( + new HttpRequestMetadata(null, 200, null, null, "NullPointerException", 0), + defaultClientSetup, + r -> responseSetupper(r, 200, null) + ), +// + Triple.of( + new HttpRequestMetadata(null, 0, "bar url", null, "java.net.ConnectException: Connection refused", 0), + (c, r) -> + when(c.getServiceInputStream(any(), eq(true))).thenThrow(new ExceptionWithRequestInfo(HttpMethod.GET, "bar url", + new ProcessingException("java.net.ConnectException: Connection refused: connect"))), + r -> responseSetupper(r, 200, defaultResponseBody) + ), + + Triple.of( + new HttpRequestMetadata(null, 500, null, null, "error while retrieving model", 0), + defaultClientSetup, + r -> responseSetupper(r, 500, defaultResponseBody) + ), + + Triple.of( + new HttpRequestMetadata(null, 404, null, null, "updating vid probe configuration", 0), + defaultClientSetup, + r -> responseSetupper(r, 404, defaultResponseBody) + ) + + ).map(t -> ImmutableList.of(t.getLeft(), t.getMiddle(), t.getRight()).toArray()).collect(Collectors.toList()).toArray(new Object[][]{}); + } + + @Test(dataProvider = "executionResults") + public void whenClientReturnWithError_thenProbeSdcByGettingModelDescribes(HttpRequestMetadata expectedMetadata, + BiConsumer<AsdcClient, HttpResponse<InputStream>> clientSetup, + Consumer<HttpResponse<InputStream>> responseSetup) { + + final HttpResponse<InputStream> mockResponse = mock(HttpResponse.class); + clientSetup.accept(asdcClientMock, mockResponse); + responseSetup.accept(mockResponse); + + ExternalComponentStatus sdcComponentStatus = vidService.probeSdcByGettingModel(UUID.randomUUID()); + assertThat(sdcComponentStatus.getComponent(), is(ExternalComponentStatus.Component.SDC)); + assertThat(sdcComponentStatus.getMetadata(), instanceOf(HttpRequestMetadata.class)); + + HttpRequestMetadata componentStatusMetadata = ((HttpRequestMetadata) sdcComponentStatus.getMetadata()); + assertThat(componentStatusMetadata.getDescription(), containsString(defaultIfNull(expectedMetadata.getDescription(), "OK"))); + assertThat(componentStatusMetadata.getHttpMethod(), equalTo(defaultIfNull(expectedMetadata.getHttpMethod(), HttpMethod.GET))); + assertThat(componentStatusMetadata.getHttpCode(), equalTo(expectedMetadata.getHttpCode())); + assertThat(componentStatusMetadata.getUrl(), equalTo(defaultIfNull(expectedMetadata.getUrl(), "foo url"))); + + assertThat(sdcComponentStatus.isAvailable(), is(false)); + } + } diff --git a/vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java b/vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java index 3f5bf8163..848f80b1e 100644 --- a/vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java +++ b/vid-app-common/src/test/java/org/onap/vid/testUtils/StubServerUtil.java @@ -64,7 +64,7 @@ public class StubServerUtil { return String.format("%s://localhost:%s/%s", protocol, stubServer.getPort(), relativePath); } - public void prepareGetCall(String path, Action actionToReturn,Object returnObj, Action expectedAction, String contentType) throws JsonProcessingException { + public void prepareGetCall(String path, Action actionToReturn, Action expectedAction, String contentType) throws JsonProcessingException { whenHttp(stubServer) .match(Condition.get(path)) .then(expectedAction, actionToReturn, contentType(contentType)); @@ -72,7 +72,7 @@ public class StubServerUtil { public void prepareGetCall(String path, Object returnObj, Action expectedAction) throws JsonProcessingException { - prepareGetCall(path, jsonContent(returnObj),returnObj, expectedAction, APPLICATION_JSON); + prepareGetCall(path, jsonContent(returnObj), expectedAction, APPLICATION_JSON); } public void prepareDeleteCall(String path, Object returnObj, Action expectedAction) throws JsonProcessingException { diff --git a/vid-automation/TestNg-ApiTest.xml b/vid-automation/TestNg-ApiTest.xml index 9e9380faa..641f3eba6 100644 --- a/vid-automation/TestNg-ApiTest.xml +++ b/vid-automation/TestNg-ApiTest.xml @@ -3,8 +3,7 @@ <suite verbose="1" name="VID API Tests" annotations="JDK"> <listeners> - <listener class-name="vid.automation.test.infra.FeatureTogglingTestngTransformer" /> - <listener class-name="vid.automation.test.infra.SkipTestUntilTestngTransformer"/> + <listener class-name="vid.automation.test.infra.SkipTestsTestngTransformer" /> </listeners> <test name="test"> diff --git a/vid-automation/TestNg-UI-half.xml b/vid-automation/TestNg-UI-half.xml index b19073869..27abcd76c 100644 --- a/vid-automation/TestNg-UI-half.xml +++ b/vid-automation/TestNg-UI-half.xml @@ -2,8 +2,7 @@ <suite verbose="1" name="VID UI Tests" annotations="JDK"> <listeners> - <listener class-name="vid.automation.test.infra.FeatureTogglingTestngTransformer"/> - <listener class-name="vid.automation.test.infra.SkipTestUntilTestngTransformer"/> + <listener class-name="vid.automation.test.infra.SkipTestsTestngTransformer"/> </listeners> <test name="test"> <method-selectors> diff --git a/vid-automation/TestNg-dev.xml b/vid-automation/TestNg-dev.xml index 3dc9d749d..d50785eb5 100644 --- a/vid-automation/TestNg-dev.xml +++ b/vid-automation/TestNg-dev.xml @@ -4,8 +4,7 @@ <suite verbose="1" name="VID UI Tests" annotations="JDK"> <listeners> - <listener class-name="vid.automation.test.infra.FeatureTogglingTestngTransformer"/> - <listener class-name="vid.automation.test.infra.SkipTestUntilTestngTransformer"/> + <listener class-name="vid.automation.test.infra.SkipTestsTestngTransformer"/> </listeners> <test name="test"> <groups> diff --git a/vid-automation/src/main/java/vid/automation/test/infra/SkipTestUntilTestngTransformer.java b/vid-automation/src/main/java/vid/automation/test/infra/SkipTestUntilTestngTransformer.java deleted file mode 100644 index 2d2ce7cde..000000000 --- a/vid-automation/src/main/java/vid/automation/test/infra/SkipTestUntilTestngTransformer.java +++ /dev/null @@ -1,57 +0,0 @@ -package vid.automation.test.infra; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.time.LocalDate; -import org.testng.IAnnotationTransformer; -import org.testng.annotations.ITestAnnotation; - -/* -TestNg listener that skip tests that are annotated with SkipTestUntil annotation -Pay attention that this listener shall be configured in the testng.xml (or command line) -*/ -public class SkipTestUntilTestngTransformer implements IAnnotationTransformer { - - @Override - public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { - - if (testMethod!=null) { - try { - - if (!annotation.getEnabled()) { - return; - } - - if (!testMethod.isAnnotationPresent(SkipTestUntil.class)) { - return; - } - - String dateAsStr = testMethod.getAnnotation(SkipTestUntil.class).value(); - if (shallDisableTest(dateAsStr)) { - disableTest(annotation, testMethod.getDeclaringClass().getName(), dateAsStr); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - private boolean shallDisableTest(String dateAsStr) { - try { - return LocalDate.now().isBefore(LocalDate.parse(dateAsStr)); - } - catch (RuntimeException exception) { - System.out.println("Failure during processing of SkipTestUntil annotation value is " + dateAsStr); - exception.printStackTrace(); - return false; - } - } - - private void disableTest(ITestAnnotation annotation, String name, String dateAsStr) { - System.out.println("Ignore "+ name+" till "+dateAsStr); - annotation.setEnabled(false); - } - -} - diff --git a/vid-automation/src/main/java/vid/automation/test/infra/FeatureTogglingTestngTransformer.java b/vid-automation/src/main/java/vid/automation/test/infra/SkipTestsTestngTransformer.java index 46794da10..ed9aaaf69 100644 --- a/vid-automation/src/main/java/vid/automation/test/infra/FeatureTogglingTestngTransformer.java +++ b/vid-automation/src/main/java/vid/automation/test/infra/SkipTestsTestngTransformer.java @@ -1,5 +1,6 @@ package vid.automation.test.infra; +import java.time.LocalDate; import org.testng.IAnnotationTransformer; import org.testng.annotations.ITestAnnotation; import org.togglz.core.context.StaticFeatureManagerProvider; @@ -9,15 +10,21 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; /* -In order to skip test classes regards the state of feature flag we add this listener to our testng configuration +This transformer skip test we want to ignore during running VID tests. +Pay attention that this listener shall be configured in the testng.xml (or command line) +It can't be used as Listener annotation of base class + +FeatureTogglingTest: There are 2 ways to annotate that tests required featureFlags to be active : In method level - with @FeatureTogglingTest on the test method and list of Required Feature flags on In Class level - with @FeatureTogglingTest on the test class and list of Required Feature flags on For each test annotation of method level, we check if the test shall whole class shall run regards the features flag test. -Pay attention that this listener shall be configured in the testng.xml (or command line) -It can't be used as Listener annotation of base class + +SkipTestUntil: +If test annotated with SkipTestUntil the transformer check if the due date has already pass + */ -public class FeatureTogglingTestngTransformer implements IAnnotationTransformer { +public class SkipTestsTestngTransformer implements IAnnotationTransformer { @Override public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { @@ -29,23 +36,28 @@ public class FeatureTogglingTestngTransformer implements IAnnotationTransformer return; } - if (isIgnoreTest(testMethod)) { - disableTest(annotation, testMethod.getDeclaringClass().getName()); + if (isIgnoreFeatureToggledTest(testMethod)) { + disableTest(annotation, testMethod.getName()); return; } - if (isIgnoreTest(testMethod.getDeclaringClass())) { + if (isIgnoreFeatureToggledTest(testMethod.getDeclaringClass())) { disableTest(annotation, testMethod.getDeclaringClass().getName()); return; } + if (isIgnoreSkipUntilTest(testMethod)) { + disableTest(annotation, testMethod.getName()); + return; + } + } catch (Exception e) { e.printStackTrace(); } } } - private boolean isIgnoreTest(AnnotatedElement annotatedElement) { + private boolean isIgnoreFeatureToggledTest(AnnotatedElement annotatedElement) { return (annotatedElement.isAnnotationPresent(FeatureTogglingTest.class) && shallDisableTest(annotatedElement.getAnnotation(FeatureTogglingTest.class))); @@ -68,9 +80,24 @@ public class FeatureTogglingTestngTransformer implements IAnnotationTransformer } private void disableTest(ITestAnnotation annotation, String name) { - System.out.println("Ignore "+ name+" due to feature flags configuration"); + System.out.println("Ignore "+ name+" due to annotation"); annotation.setEnabled(false); } + private boolean isIgnoreSkipUntilTest(AnnotatedElement annotatedElement) { + if (!annotatedElement.isAnnotationPresent(SkipTestUntil.class)) { + return false; + } + + String dateAsStr = annotatedElement.getAnnotation(SkipTestUntil.class).value(); + try { + return LocalDate.now().isBefore(LocalDate.parse(dateAsStr)); + } + catch (RuntimeException exception) { + System.out.println("Failure during processing of SkipTestUntil annotation value is " + dateAsStr); + exception.printStackTrace(); + return false; + } + } } diff --git a/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java b/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java index a550cde4c..5ed302468 100644 --- a/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java +++ b/vid-automation/src/test/java/org/onap/vid/api/ProbeApiTest.java @@ -142,7 +142,7 @@ public class ProbeApiTest extends BaseApiTest { 200, SCHEDULER_PATH, "this payload is an invalid json", - "javax.ws.rs.ProcessingException" + "com.fasterxml.jackson.core.JsonParseException" ) )) }, @@ -168,7 +168,7 @@ public class ProbeApiTest extends BaseApiTest { 406, MSO_QUERY_PARAMS, "this payload is an invalid json", - "org.apache.http.HttpException: Get with status=406 (200 or 202 expected), url= http" + "MSO returned no orchestration requests" ) ), new ExternalComponentStatus(ExternalComponentStatus.Component.SDC, false, @@ -185,7 +185,7 @@ public class ProbeApiTest extends BaseApiTest { 400, SCHEDULER_PATH, "this payload is an invalid json", - "org.apache.http.HttpException: Get with status = 400, url = " + SCHEDULER_PATH + "org.apache.http.HttpException" ) )) } @@ -203,7 +203,7 @@ public class ProbeApiTest extends BaseApiTest { new ParameterizedTypeReference<List<ExternalComponentStatus>>() { }); List<ExternalComponentStatus> probeResults = response.getBody(); - Assert.assertEquals(4, probeResults.size()); + Assert.assertEquals(5, probeResults.size()); assertResultAsExpected(ExternalComponentStatus.Component.AAI, probeResults, expectedStatuses); assertResultAsExpected(ExternalComponentStatus.Component.SDC, probeResults, expectedStatuses); assertResultAsExpected(ExternalComponentStatus.Component.MSO, probeResults, expectedStatuses); diff --git a/vid-automation/src/test/resources/sdcApiTest/minMaxInitialExpectedResponse.json b/vid-automation/src/test/resources/sdcApiTest/minMaxInitialExpectedResponse.json index 2b648c1ed..e10872b00 100644 --- a/vid-automation/src/test/resources/sdcApiTest/minMaxInitialExpectedResponse.json +++ b/vid-automation/src/test/resources/sdcApiTest/minMaxInitialExpectedResponse.json @@ -25,6 +25,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "AV_vPE" }, "2017488pasqualevpe20_bandwidth": { @@ -34,6 +38,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "10" }, "2017488pasqualevpe20_bandwidth_units": { @@ -43,6 +51,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "Gbps" }, "2017488pasqualevpe20_AIC_CLLI": { @@ -52,6 +64,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "ATLMY8GA" }, "2017488pasqualevpe20_vnf_config_template_version": { @@ -61,6 +77,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "17.2" }, "2017488pasqualevpe20_vnf_instance_name": { @@ -70,6 +90,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "mtnj309me6" } } @@ -90,6 +114,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "17.2" }, "bandwidth_units": { @@ -99,6 +127,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "Gbps" }, "bandwidth": { @@ -108,6 +140,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "10" }, "AIC_CLLI": { @@ -117,6 +153,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "ATLMY8GA" }, "ASN": { @@ -126,6 +166,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "AV_vPE" }, "vnf_instance_name": { @@ -135,6 +179,10 @@ "inputProperties": null, "constraints": [], "required": true, + "templateName": null, + "templateUUID": null, + "templateInvariantUUID": null, + "templateCustomizationUUID": null, "default": "mtnj309me6" } }, diff --git a/vid-webpack-master/cypress/integration/iFrames/softDeleteAndResume.e2e.ts b/vid-webpack-master/cypress/integration/iFrames/softDeleteAndResume.e2e.ts index 02bc2728d..b83268ece 100644 --- a/vid-webpack-master/cypress/integration/iFrames/softDeleteAndResume.e2e.ts +++ b/vid-webpack-master/cypress/integration/iFrames/softDeleteAndResume.e2e.ts @@ -1,6 +1,5 @@ ///<reference path="../../../node_modules/cypress/types/index.d.ts"/> import {JsonBuilder} from '../../support/jsonBuilders/jsonBuilder'; -import {PnfModel} from '../../support/jsonBuilders/models/pnf.model'; import {ServiceModel} from '../../support/jsonBuilders/models/service.model'; import {AaiServiceInstancesModel} from '../../support/jsonBuilders/models/serviceInstances.model'; import {AAISubDetailsModel} from '../../support/jsonBuilders/models/aaiSubDetails.model'; @@ -76,7 +75,7 @@ describe('Soft delete tests', function () { it(`Resume button display in orch status - pendingactivation, assigned - feature FLAG_VF_MODULE_RESUME_STATUS_CREATE - is OFF`, function () { - cy.readFile('/cypress/support/jsonBuilders/mocks/jsons/flags.json').then((res) => { + cy.readFile('/cypress/support/jsonBuilders/mocks/jsons/flags.json').then(() => { cy.server() .route({ method: 'GET', @@ -121,17 +120,17 @@ describe('Soft delete tests', function () { cy.visit('/serviceModels.htm#/instantiate?subscriberId=e433710f-9217-458d-a79d-1c7aff376d89&subscriberName=SILVIA%20ROBBINS&serviceType=TYLER%20SILVIA&serviceInstanceId=3f93c7cb-2fd0-4557-9514-e189b7b04f9d&aaiModelVersionId=6e59c5de-f052-46fa-aa7e-2fca9d674c44&isPermitted=true'); cy.wait('@service-complexService'); checkSoftDeleteAndDeletePopup('gg', 'vfModuleTreeNode-assigned', false, true); - cy.selectDropdownOptionByText('lcpRegion', 'AAIAIC25'); + cy.selectDropdownOptionByText('lcpRegion', 'AAIAIC25 (AIC)'); cy.getElementByDataTestsId('confirmResumeDeleteButton').should('have.attr', 'disabled'); cy.typeToInput("lcpRegionText", "just another region"); cy.getElementByDataTestsId('confirmResumeDeleteButton').should('have.attr', 'disabled'); cy.selectDropdownOptionByText('tenant', 'USP-SIP-IC-24335-T-01'); cy.getElementByDataTestsId('confirmResumeDeleteButton').should('not.have.attr', 'disabled'); - cy.selectDropdownOptionByText('lcpRegion', 'hvf6'); + cy.selectDropdownOptionByText('lcpRegion', 'hvf6 (AIC)'); cy.getElementByDataTestsId('confirmResumeDeleteButton').should('have.attr', 'disabled'); cy.selectDropdownOptionByText('tenant', 'AIN Web Tool-15-D-testalexandria'); cy.getElementByDataTestsId('confirmResumeDeleteButton').should('not.have.attr', 'disabled'); - cy.getElementByDataTestsId('cancel').click({force: true}) + cy.getElementByDataTestsId('cancel').click({force: true}); cy.getElementByDataTestsId('confirmResumeDeleteButton').should('not.be.visible'); }); @@ -190,10 +189,10 @@ describe('Soft delete tests', function () { }); function checkLegacyRegion() { - checkIsLegacyRegionTextIsDisplay('AAIAIC25', true); - checkIsLegacyRegionTextIsDisplay('olson3', false); - checkIsLegacyRegionTextIsDisplay('olson5a', false); - checkIsLegacyRegionTextIsDisplay('hvf6', false); + checkIsLegacyRegionTextIsDisplay('AAIAIC25 (AIC)', true); + checkIsLegacyRegionTextIsDisplay('olson3 (AIC)', false); + checkIsLegacyRegionTextIsDisplay('olson5a (AIC)', false); + checkIsLegacyRegionTextIsDisplay('hvf6 (AIC)', false); } function checkIsLegacyRegionTextIsDisplay(lcpRegionName: string, isVisible: boolean) { |