--- /dev/null
+---
+# .readthedocs.yml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+# Required
+version: 2
+
+formats:
+ - htmlzip
+
+build:
+ image: latest
+
+python:
+ version: 3.7
+ install:
+ - requirements: docs/requirements-docs.txt
+
+sphinx:
+ configuration: docs/conf.py
--- /dev/null
+Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
<parent>
<groupId>org.onap.vid</groupId>
<artifactId>vid-parent</artifactId>
- <version>6.0.0-SNAPSHOT</version>
+ <version>6.0.3-SNAPSHOT</version>
</parent>
<packaging>pom</packaging>
<descriptor>assembly/assembly-for-plugin.xml</descriptor>
</assembly>
<tags>
- <tag>5.0-STAGING-latest</tag>
+ <tag>6.0-STAGING-latest</tag>
<tag>latest</tag>
<tag>${docker.tag}</tag>
<tag>${docker.latest.tag}</tag>
--- /dev/null
+/.tox
+/_build/*
+/__pycache__/*
--- /dev/null
+.ribbon {
+ z-index: 1000;
+ background-color: #a00;
+ overflow: hidden;
+ white-space: nowrap;
+ position: fixed;
+ top: 25px;
+ right: -50px;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg);
+ -webkit-box-shadow: 0 0 10px #888;
+ -moz-box-shadow: 0 0 10px #888;
+ box-shadow: 0 0 10px #888;
+
+}
+
+.ribbon a {
+ border: 1px solid #faa;
+ color: #fff;
+ display: block;
+ font: bold 81.25% 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ margin: 1px 0;
+ padding: 10px 50px;
+ text-align: center;
+ text-decoration: none;
+ text-shadow: 0 0 5px #444;
+ transition: 0.5s;
+}
+
+.ribbon a:hover {
+ background: #c11;
+ color: #fff;
+}
+
+
+/* override table width restrictions */
+@media screen and (min-width: 767px) {
+
+ .wy-table-responsive table td, .wy-table-responsive table th {
+ /* !important prevents the common CSS stylesheets from overriding
+ this as on RTD they are loaded after this stylesheet */
+ white-space: normal !important;
+ }
+
+ .wy-table-responsive {
+ overflow: visible !important;
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .wy-table-responsive table td {
+ white-space: nowrap;
+ }
+}
+
+/* fix width of the screen */
+
+.wy-nav-content {
+ max-width: none;
+}
--- /dev/null
+from docs_conf.conf import *
+
+branch = 'latest'
+master_doc = 'index'
+
+linkcheck_ignore = [
+ 'http://localhost',
+]
+
+intersphinx_mapping = {}
+
+html_last_updated_fmt = '%d-%b-%y %H:%M'
+
+def setup(app):
+ app.add_stylesheet("css/ribbon_onap.css")
--- /dev/null
+---
+project_cfg: onap
+project: onap
+
+# Change this to ReleaseBranchName to modify the header
+default-version: latest
+#
VID Release Notes
=================
-Version: El-Alto (6.0.x)
+Version: Frankfurt (6.0.x)
------------------------
**Known Issues**
--- /dev/null
+tox
+Sphinx
+doc8
+docutils
+setuptools
+six
+sphinx_rtd_theme>=0.4.3
+sphinxcontrib-blockdiag
+sphinxcontrib-needs>=0.2.3
+sphinxcontrib-nwdiag
+sphinxcontrib-seqdiag
+sphinxcontrib-swaggerdoc
+sphinxcontrib-plantuml
+sphinx_bootstrap_theme
+lfdocs-conf
--- /dev/null
+[tox]
+minversion = 1.6
+envlist = docs,
+skipsdist = true
+
+[testenv:docs]
+basepython = python3
+deps = -r{toxinidir}/requirements-docs.txt
+commands =
+ sphinx-build -b html -n -d {envtmpdir}/doctrees ./ {toxinidir}/_build/html
+ echo "Generated docs available in {toxinidir}/_build/html"
+whitelist_externals =
+ echo
+ git
+ sh
+
+[testenv:docs-linkcheck]
+basepython = python3
+#deps = -r{toxinidir}/requirements-docs.txt
+commands = echo "Link Checking not enforced"
+#commands = sphinx-build -b linkcheck -d {envtmpdir}/doctrees ./ {toxinidir}/_build/linkcheck
+whitelist_externals = echo
the Portal team. -->
<groupId>org.onap.vid</groupId>
<artifactId>epsdk-app-onap</artifactId>
- <version>6.0.0-SNAPSHOT</version>
+ <version>6.0.3-SNAPSHOT</version>
<packaging>war</packaging>
<name>ECOMP SDK Webapp for OpenSource</name>
<description>ECOMP SDK Web Application for public release</description>
<encoding>UTF-8</encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <epsdk.version>2.5.0</epsdk.version>
+ <epsdk.version>2.6.0</epsdk.version>
+ <epsdk.overlay.version>2.5.0</epsdk.overlay.version>
<jackson.version>2.10.1</jackson.version>
<jackson.databind.version>2.10.1</jackson.databind.version>
- <springframework.version>5.2.0.RELEASE</springframework.version>
+ <springframework.version>5.2.3.RELEASE</springframework.version>
<!-- epsdk-core is importing this class, which is only on spring-orm 4 but not in orm 5:
org.springframework.orm.hibernate4.HibernateTransactionManager
so following orm.version lets epsdk-core find it -->
<dependency>
<groupId>org.onap.portal.sdk</groupId>
<artifactId>epsdk-app-overlay</artifactId>
- <version>${epsdk.version}</version>
+ <version>${epsdk.overlay.version}</version>
<type>war</type>
</dependency>
<dependency>
mso.restapi.operationalEnvironment.cloudResourcesRequests.status=${mso.restapi.cloudResourcesRequestsApiRoot}?requestId=<request_id>
mso.displayTestAPIOnScreen=true
-mso.defaultTestAPI=VNF_API
+mso.defaultTestAPI=GR_API
mso.maxOpenedInstantiationRequests=200
mso.asyncPollingIntervalSeconds=1
refreshTimeInstantiationDashboard=10
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ page isELIgnored="false"%>
-<%@ page import="org.onap.portalsdk.core.util.SystemProperties"%>
-<%@ page import="org.onap.portalsdk.core.onboarding.util.PortalApiProperties"%>
<%@ page import="org.onap.portalsdk.core.onboarding.util.PortalApiConstants"%>
-<%@ page import="org.onap.portalsdk.core.domain.MenuData"%>
+<%@ page import="org.onap.portalsdk.core.onboarding.util.PortalApiProperties"%>
+<%@ page import="org.onap.portalsdk.core.util.SystemProperties"%>
<link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/ebz_header/header.css">
<link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/ebz_header/portal_ebz_header.css">
-<link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/style.css" >
+<link rel="stylesheet" type="text/css" href="app/fusion/external/ebz/sandbox/styles/style.css">
<%--<script src= "app/fusion/external/ebz/angular_js/angular.js"></script> --%>
"parentMenuId": null,
"url": ""
},
- {
- "menuId": 90,
- "column": 1,
- "text": "Google",
- "parentMenuId": 1,
- "url": "http://google.com"
- },
- {
- "menuId": 91,
- "column": 1,
- "text": "Mike Little's Coffee Cup",
- "parentMenuId": 2,
- "url": "http://coffee.com"
- },
- {
- "menuId": 92,
- "column": 2,
- "text": "Andy and his Astrophotgraphy",
- "parentMenuId": 3,
- "url": "http://nightskypix.com"
- },
- {
- "menuId": 93,
- "column": 1,
- "text": "JSONLint",
- "parentMenuId": 4,
- "url": "http://http://jsonlint.com"
- },
- {
- "menuId": 96,
- "column": 3,
- "text": "3rd Level App1c R200",
- "parentMenuId": 4,
- "url": "http://app1c.com"
- },
- {
- "menuId": 97,
- "column": 1,
- "text": "3rd Level App4b R16",
- "parentMenuId": 5,
- "url": "http://app4b.com"
- },
- {
- "menuId": 98,
- "column": 2,
- "text": "3rd Level App2b R16",
- "parentMenuId": 5,
- "url": "http://app2b.com"
- },
{
"menuId": 99,
"column": 1,
$scope.megaMenuDataObject = menuStructureConvert($scope.jsonMenuData);
// $log.debug(JSON.stringify($scope.jsonMenuData));
}
+
+ LeftMenuService.getLeftMenu().then(function (response) {
+ var menu = {
+ parentList: JSON.parse(response.data),
+ childItemList: JSON.parse(response.data2)
+ };
+
+ try {
+
var childItemList="";
var parentList = "";
try{
- childItemList = ${menu.childItemList};
- parentList = ${menu.parentList};
+ childItemList = menu.childItemList;
+ parentList = menu.parentList;
}catch(err){
console.log("ebz_header: failed to get child/parent lists", err);
}
$timeout(function() {
detectScrollEvent();
}, 800);
-
+
+ } catch (e) {
+ console.log("error happened while trying to get app menu " + e);
+ }
+ }, function (error) {
+ console.log('getLeftMenu failed', error);
+ });
+
});
app.filter("ellipsis", function(){
major=6
minor=0
-patch=0
+patch=3
base_version=${major}.${minor}.${patch}
* FLAG_2004_INSTANTIATION_TEMPLATES_POPUP
Enables a designated Templates selection modal, accessible when creating a new instance through "Browse SDC".
+* FLAG_2006_VFM_SDNC_PRELOAD_FILES
+ Enables upload files when SDNC preload checkbox is checked
+
* FLAG_2002_UNLIMITED_MAX
when flag is true and max_instances is not declare than user can add unlimited VND, NETWORK, VFMODULE,
User can duplicate up to 10 record in single time.
If the flag is false and max_instances is not declare the max will be 1 else max_instances value.
+
+* FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO
+ On the "audit info" modal (available on Instantiation Status page), shows a link navigating to
+ the read-only RETRY page with more audit info.
+
+* FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY
+ When flag is true the user will be provided with edit permissions by owning entity id even the user have no permission by Subscriber,
+ when the flag is false the user provided with edit permission by Subscriber.
+
+* FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF
+ When flag is true new VF Modules on Alacarte service will inherit LCP-Region and Tenant from parent VNF.
+ When off, user is requested to specify LCP-Region and Tenant for each VF Module.
\ No newline at end of file
<modelVersion>4.0.0</modelVersion>
<groupId>org.onap.vid</groupId>
<artifactId>vid-parent</artifactId>
- <version>6.0.0-SNAPSHOT</version>
+ <version>6.0.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>vid</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <build.version>6.0.0-SNAPSHOT</build.version>
+ <build.version>6.0.3-SNAPSHOT</build.version>
<nexusproxy>https://nexus.onap.org</nexusproxy>
<snapshotNexusPath>content/repositories/snapshots/</snapshotNexusPath>
<releaseNexusPath>content/repositories/releases/</releaseNexusPath>
--- /dev/null
+distribution_type: 'container'
+container_release_tag: '6.0.1'
+project: 'vid'
+log_dir: 'vid-maven-docker-stage-master/233/'
+ref: e8414b1fe839291418ead3a7e5a64bf382dc1121
+containers:
+ - name: 'vid'
+ version: '6.0.1-20200109T025909Z'
\ No newline at end of file
--- /dev/null
+distribution_type: 'container'
+container_release_tag: '6.0.2'
+project: 'vid'
+log_dir: 'vid-maven-docker-stage-master/253/'
+ref: 667fbe07aae6f9669127e9e0212f6f83c87b0d0a
+containers:
+ - name: 'vid'
+ version: '6.0.2-20200126T025724Z'
\ No newline at end of file
major=6
minor=0
-patch=0
+patch=3
base_version=${major}.${minor}.${patch}
inherit from a parent maven module. -->
<groupId>org.onap.vid</groupId>
<artifactId>vid-app-common</artifactId>
- <version>6.0.0-SNAPSHOT</version>
+ <version>6.0.3-SNAPSHOT</version>
<packaging>war</packaging>
<name>VID Common</name>
<description>VID Common code for opensource version</description>
<encoding>UTF-8</encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <epsdk.version>2.5.0</epsdk.version>
- <springframework.version>5.2.0.RELEASE</springframework.version>
+ <epsdk.version>2.6.0</epsdk.version>
+ <epsdk.overlay.version>2.5.0</epsdk.overlay.version>
+ <springframework.version>5.2.3.RELEASE</springframework.version>
<springframework.orm.version>4.3.22.RELEASE</springframework.orm.version>
<!-- epsdk-core is importing this class, which is only on spring-orm 4 but not in orm 5:
org.springframework.orm.hibernate4.HibernateTransactionManager
<dependency>
<groupId>org.onap.portal.sdk</groupId>
<artifactId>epsdk-app-overlay</artifactId>
- <version>${epsdk.version}</version>
+ <version>${epsdk.overlay.version}</version>
<type>war</type>
</dependency>
<dependency>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>1.4</version>
+ </dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
}
@Override
- public AaiResponse getServicesByOwningEntityId(List<String> owningEntityIds){
+ public AaiResponse<OwningEntityResponse> getServicesByOwningEntityId(List<String> owningEntityIds){
Response resp = doAaiGet(getUrlFromLIst("business/owning-entities?", "owning-entity-id=", owningEntityIds), false);
return processAaiResponse(resp, OwningEntityResponse.class, null);
}
@Override
- public AaiResponse getServicesByProjectNames(List<String> projectNames){
+ public AaiResponse<ProjectResponse> getServicesByProjectNames(List<String> projectNames){
Response resp = doAaiGet(getUrlFromLIst("business/projects?", "project-name=", projectNames), false);
return processAaiResponse(resp, ProjectResponse.class, null);
}
}
@Override
- public AaiResponse getSubscriberData(String subscriberId, boolean omitServiceInstances) {
+ public AaiResponse<Services> getSubscriberData(String subscriberId, boolean omitServiceInstances) {
String depth = omitServiceInstances ? "1" : "2";
- AaiResponse subscriberDataResponse;
+ AaiResponse<Services> subscriberDataResponse;
Response resp = doAaiGet(BUSINESS_CUSTOMERS_CUSTOMER + subscriberId + "?depth=" + depth, false);
subscriberDataResponse = processAaiResponse(resp, Services.class, null);
return subscriberDataResponse;
}
}
- private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody) {
+ private <T> AaiResponse<T> processAaiResponse(Response resp, Class<? extends T> classType, String responseBody) {
return processAaiResponse(resp, classType, responseBody, VidObjectMapperType.CODEHAUS);
}
import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.onap.vid.aai.model.ModelVer;
+import org.onap.vid.aai.model.OwningEntityResponse;
import org.onap.vid.aai.model.PortDetailsTranslator;
+import org.onap.vid.aai.model.ProjectResponse;
import org.onap.vid.aai.model.Properties;
import org.onap.vid.aai.model.ResourceType;
import org.onap.vid.model.SubscriberList;
AaiResponse<SubscriberList> getAllSubscribers();
- AaiResponse getSubscriberData(String subscriberId, boolean omitServiceInstances);
+ AaiResponse<Services> getSubscriberData(String subscriberId, boolean omitServiceInstances);
AaiResponse getServices();
- AaiResponse getServicesByOwningEntityId(List<String> owningEntityIds);
+ AaiResponse<OwningEntityResponse> getServicesByOwningEntityId(List<String> owningEntityIds);
AaiResponse<GetTenantsResponse[]> getTenants(String globalCustomerId, String serviceType);
ModelVer getLatestVersionByInvariantId(String modelInvariantId);
- AaiResponse getServicesByProjectNames(List<String> projectNames);
+ AaiResponse<ProjectResponse> getServicesByProjectNames(List<String> projectNames);
AaiResponse getServiceModelsByDistributionStatus();
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.onap.vid.aai.model.RelationshipList;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ServiceInstance {
@JsonProperty("model-version-id")
public String modelVersionId;
+ @JsonProperty("relationship-list")
+ public RelationshipList relationshipList;
+
}
package org.onap.vid.asdc.beans;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.Collection;
import java.util.UUID;
private Collection<SubResource> resources;
private String orchestrationType;
+
+ @JsonInclude(NON_NULL)
+ private Boolean isInstantiationTemplateExists;
public static class ServiceBuilder {
return orchestrationType;
}
+ public Boolean getIsInstantiationTemplateExists() {
+ return isInstantiationTemplateExists;
+ }
+
+
public void setUuid(String uuid) {
this.uuid = uuid;
}
this.orchestrationType = orchestrationType;
}
+ public void setIsInstantiationTemplateExists(Boolean isInstantiationTemplateExists) {
+ this.isInstantiationTemplateExists = isInstantiationTemplateExists;
+ }
+
@Override
public String toString() {
return uuid;
}
@Override
+
public int hashCode() {
return UUID.fromString(getUuid()).hashCode();
}
import org.onap.vid.aai.util.AAIRestInterface;
import org.onap.vid.model.VersionByInvariantIdsRequest;
import org.onap.vid.properties.Features;
-import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.roles.RoleValidator;
import org.onap.vid.services.AaiService;
@RequestMapping(value = "/aai_get_services", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> doGetServices(HttpServletRequest request) throws IOException {
- RoleValidator roleValidator = RoleValidator.by(roleProvider.getUserRoles(request));
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse subscriberList = aaiService.getServices(roleValidator);
return aaiResponseToResponseEntity(subscriberList);
@RequestMapping(value = "/aai_get_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getFullSubscriberList(HttpServletRequest request) throws IOException {
ResponseEntity<String> responseEntity;
- RoleValidator roleValidator = RoleValidator.by(roleProvider.getUserRoles(request));
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
SubscriberFilteredResults subscriberList = aaiService.getFullSubscriberList(roleValidator);
if (subscriberList.getHttpCode() == 200) {
responseEntity = new ResponseEntity<>(objectMapper.writeValueAsString(subscriberList.getSubscriberList()),
@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 {
- List<Role> roles = roleProvider.getUserRoles(request);
- RoleValidator roleValidator = RoleValidator.by(roles);
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
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();
@RequestParam(value = "owningEntity", required = false) List<String> owningEntities) throws IOException {
ResponseEntity responseEntity;
- List<Role> roles = roleProvider.getUserRoles(request);
- RoleValidator roleValidator = RoleValidator.by(roles);
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse<ServiceInstancesSearchResults> searchResult = aaiService
.getServiceInstanceSearchResults(subscriberId, instanceIdentifier, roleValidator, owningEntities, projects);
ResponseEntity responseEntity;
try {
- List<Role> roles = roleProvider.getUserRoles(request);
- RoleValidator roleValidator = RoleValidator.by(roles);
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse<GetTenantsResponse[]> response = aaiService
.getTenants(globalCustomerId, serviceType, roleValidator);
if (response.getHttpCode() == 200) {
import org.onap.vid.model.aaiTree.RelatedVnf;
import org.onap.vid.model.aaiTree.VpnBinding;
import org.onap.vid.properties.Features;
+import org.onap.vid.roles.PermissionPropertiesSubscriberAndServiceType;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.services.AaiService;
import org.springframework.beans.factory.annotation.Autowired;
final boolean isEditPermitted = roleProvider
.getUserRolesValidator(request)
- .isServicePermitted(subscriberId, serviceType);
+ .isServicePermitted(new PermissionPropertiesSubscriberAndServiceType(subscriberId, serviceType));
return new Permissions(isEditPermitted);
}
import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
import org.onap.vid.mso.MsoResponseWrapper2;
import org.onap.vid.properties.Features;
+import org.onap.vid.roles.AllPermissionProperties;
import org.onap.vid.roles.RoleProvider;
+import org.onap.vid.roles.RoleValidator;
import org.onap.vid.services.AsyncInstantiationBusinessLogic;
import org.onap.vid.services.AuditService;
import org.onap.vid.utils.SystemPropertiesWrapper;
}
private void throwExceptionIfAccessDenied(ServiceInstantiation request, HttpServletRequest httpServletRequest, String userId) {
- if (featureManager.isActive(Features.FLAG_1906_INSTANTIATION_API_USER_VALIDATION) && !roleProvider.getUserRolesValidator(httpServletRequest).isServicePermitted(request.getGlobalSubscriberId(), request.getSubscriptionServiceType())) {
- throw new AccessDeniedException(String.format("User %s is not allowed to make this request", userId));
+ if (featureManager.isActive(Features.FLAG_1906_INSTANTIATION_API_USER_VALIDATION)) {
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(httpServletRequest);
+ if (!roleValidator.isServicePermitted(new AllPermissionProperties(
+ request.getGlobalSubscriberId(),
+ request.getSubscriptionServiceType(),
+ request.getOwningEntityId()))
+ ) {
+ throw new AccessDeniedException(String.format("User %s is not allowed to make this request", userId));
+ }
}
}
}
-/*
- * ============LICENSE_START==========================================
- * ===================================================================
- * Copyright © 2018 AT&T Intellectual Property. All rights reserved.
- * ===================================================================
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- * ============LICENSE_END============================================
- *
- *
+ * ============LICENSE_END=========================================================
*/
-For the file /epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/angular-sanitize.js,
-to the extent that it contains code originating from Erik Arvidsson, that code is used under the Apache-2.0 license,
-as permitted by http://erik.eae.net/simplehtmlparser/simplehtmlparser.js.
\ No newline at end of file
+package org.onap.vid.controller;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping(PreLoadController.PRE_LOAD)
+public class PreLoadController extends VidRestrictedBaseController{
+ public static final String PRE_LOAD = "preload";
+
+ @PostMapping()
+ public Boolean postPreload (HttpServletRequest request) {
+ return true;
+ }
+}
package org.onap.vid.controller;
+import java.util.Collection;
import org.onap.portalsdk.core.controller.RestrictedBaseController;
import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
import org.onap.vid.asdc.AsdcCatalogException;
import org.onap.vid.asdc.beans.SecureServices;
+import org.onap.vid.asdc.beans.Service;
import org.onap.vid.exceptions.VidServiceUnavailableException;
import org.onap.vid.model.PombaInstance.PombaRequest;
import org.onap.vid.model.ServiceModel;
import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.services.AaiService;
+import org.onap.vid.services.InstantiationTemplatesService;
import org.onap.vid.services.PombaService;
import org.onap.vid.services.VidService;
import org.springframework.beans.factory.annotation.Autowired;
private final AaiService aaiService;
private final RoleProvider roleProvider;
private final PombaService pombaService;
+ private final InstantiationTemplatesService instantiationTemplatesService;
@Autowired
public VidController(VidService vidService, AaiService aaiService, RoleProvider roleProvider,
- PombaService pombaService) {
+ PombaService pombaService, InstantiationTemplatesService instantiationTemplatesService) {
this.vidService = vidService;
this.aaiService = aaiService;
this.roleProvider = roleProvider;
this.pombaService = pombaService;
+ this.instantiationTemplatesService = instantiationTemplatesService;
}
/**
LOG.info("Start API for browse SDC was called");
SecureServices secureServices = new SecureServices();
List<Role> roles = roleProvider.getUserRoles(request);
- secureServices.setServices(aaiService.getServicesByDistributionStatus());
+
+ Collection<Service> servicesByDistributionStatus = aaiService.getServicesByDistributionStatus();
+
+ Collection<Service> servicesWithTemplatesIndication =
+ instantiationTemplatesService.setOnEachServiceIsTemplateExists(servicesByDistributionStatus);
+
+ secureServices.setServices(servicesWithTemplatesIndication);
secureServices.setReadOnly(roleProvider.userPermissionIsReadOnly(roles));
+
return secureServices;
}
import org.onap.vid.model.serviceInstantiation.*
import org.onap.vid.mso.model.*
import org.onap.vid.mso.model.BaseResourceInstantiationRequestDetails.*
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue
import org.onap.vid.mso.rest.SubscriberInfo
import org.onap.vid.properties.Features
import org.onap.vid.services.AsyncInstantiationBusinessLogic
import org.onap.vid.services.CloudOwnerService
-import org.onap.vid.utils.JACKSON_OBJECT_MAPPER
+import org.onap.vid.services.UserParamsContainer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.togglz.core.manager.FeatureManager
//cloud configuration
val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
- val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
+ val userParams = UserParamsContainer(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
//related instance list
val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo))
relatedInstanceList.add(RelatedInstance(volumeGroupModel, vgInstanceId, vfModuleDetails.volumeGroupInstanceName))
}
- return RequestDetailsWrapper(VfModuleOrVolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters(userParams)))
+ return RequestDetailsWrapper(VfModuleOrVolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters(userParams.toALaCarte())))
}
fun generateVfModuleInstantiationRequest(
fun generateVolumeGroupInstantiationRequest(vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<VolumeGroupRequestDetails> {
val requestInfo = generateRequestInfo(vfModuleDetails.volumeGroupInstanceName, ResourceType.VOLUME_GROUP, vfModuleDetails.isRollbackOnFailure, null, userId)
val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
- val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
- val requestParameters = RequestParametersVfModuleOrVolumeGroupInstantiation(userParams, vfModuleDetails.isUsePreload, testApi)
+ val userParams = UserParamsContainer(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
+ val requestParameters = RequestParametersVfModuleOrVolumeGroupInstantiation(userParams.toALaCarte(), vfModuleDetails.isUsePreload, testApi)
val relatedInstances = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo))
vfModuleDetails.modelInfo.modelType = "volumeGroup"
private fun convertVfModuleMapToList(vfModules: Map<String, Map<String, VfModule>>): List<VfModuleMacro> {
return vfModules.values.stream().flatMap { vfModule ->
vfModule.values.stream().map { item ->
- val aggregatedParams = aggregateAllInstanceParams(extractActualInstanceParams(item.instanceParams), item.supplementaryParams)
- val aggregatedParamsConverted = JACKSON_OBJECT_MAPPER.convertValue(aggregatedParams, List::class.java)
+ val userParams = UserParamsContainer(extractActualInstanceParams(item.instanceParams), item.supplementaryParams)
VfModuleMacro(
item.modelInfo,
item.instanceName,
item.volumeGroupInstanceName,
- aggregatedParamsConverted as List<Map<String, String>>)
+ userParams.toMacroPost1806())
}
}.collect(Collectors.toList<VfModuleMacro>())
}
- fun aggregateAllInstanceParams(instanceParams: Map<String, String>?, supplementaryParams: Map<String, String>?): List<UserParamMap<String, String>> {
- var instanceParamsFinal: Map<String, String> = instanceParams ?: emptyMap()
- val supplementaryParamsFinal: Map<String, String> = supplementaryParams ?: emptyMap()
-
- if (!(instanceParamsFinal.isEmpty() && supplementaryParamsFinal.isEmpty())) {
- //remove duplicate keys from instanceParams if exist in supplementaryParams
- instanceParamsFinal = instanceParamsFinal.entries.stream()
- .filter { m -> !supplementaryParamsFinal.containsKey(m.key) }
- .collect(Collectors.toMap({ it.key }, { it.value }))
-
- //aggregate the 2 collections and format them as UserParamMap
- val aggregatedParams = UserParamMap<String, String>()
- aggregatedParams.putAll(instanceParamsFinal)
- aggregatedParams.putAll(supplementaryParamsFinal)
-
- return mutableListOf(aggregatedParams)
- }
-
- return emptyList()
- }
-
//Make sure we always get a one Map from InstanceParams
private fun extractActualInstanceParams(originalInstanceParams: List<MutableMap<String, String>>?): MutableMap<String, String> {
return if (originalInstanceParams.isNullOrEmpty() || originalInstanceParams[0].isNullOrEmpty()) {
}
}
- private fun generateUserParamList(): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> {
+ private fun generateUserParamList(): List<UserParamNameAndValue> {
return emptyList()
}
fun generateMacroServicePre1806InstantiationRequest(payload: ServiceInstantiation, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> {
val requestInfo = ServiceInstantiationRequestDetails.RequestInfo(payload.instanceName, payload.productFamilyId, VID_SOURCE, payload.isRollbackOnFailure, userId)
- val userParams = generateUserParamsNameAndValue(payload.instanceParams)
- val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, userParams)
+ val userParams = UserParamsContainer(generateSingleMapFromInstanceParams(payload.instanceParams), emptyList())
+ val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, userParams.toMacroPre1806())
val subscriberInfo = generateSubscriberInfoPre1806(payload)
val project = if (payload.projectName != null) ServiceInstantiationRequestDetails.Project(payload.projectName) else null
val owningEntity = ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.owningEntityId, payload.owningEntityName)
relatedInstanceList))
}
- private fun generateUserParamsNameAndValue(instanceParams: List<Map<String, String>>): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> {
- return instanceParams.getOrElse(0) {emptyMap()}.map{ x-> ServiceInstantiationRequestDetails.UserParamNameAndValue(x.key, x.value)}
+ private fun generateSingleMapFromInstanceParams(instanceParams: List<Map<String, String>>): Map<String, String> {
+ return if (instanceParams.isNullOrEmpty()) emptyMap() else instanceParams[0]
}
private fun generateSubscriberInfoPre1806(payload: ServiceInstantiation): SubscriberInfo {
val serviceModelInfo = serviceModelInfoFromRequest()
val modelNewestUuid = commandUtils.getNewestModelUuid(serviceModelInfo.modelInvariantId);
- check(!modelNewestUuid.equals(serviceModelInfo.modelVersionId, true)) {
- "Model version id ${serviceModelInfo.modelVersionId} is already the latest version of model's invariant id ${serviceModelInfo.modelInvariantId}" }
-
val serviceNewestModel = commandUtils.getServiceModel(modelNewestUuid);
return serviceNewestModel;
import org.onap.vid.mso.RestMsoImplementation
import org.onap.vid.properties.Features
import org.onap.vid.services.AsyncInstantiationBusinessLogic
+import org.onap.vid.utils.isNotActive
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
val vfModules:List<VfModule> = request.vfModules.values.stream().flatMap { vfKey -> vfKey.values.stream() }.collect(Collectors.toList<VfModule>())
try {
- childJobs = pushChildrenJobsToBroker(vfModules.filter { filterModuleByNeedToCreateBase(it) }, dataForChild, JobType.VolumeGroupInstantiation)
+ childJobs = pushChildrenJobsToBroker(vfModulesForChildrenJobs(vfModules), dataForChild, JobType.VolumeGroupInstantiation)
} catch (e: AsdcCatalogException) {
- LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message , e)
+ LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message, e)
//return Job.JobStatus.FAILED
throw e;
}
return Job.JobStatus.COMPLETED_WITH_NO_ACTION
}
- private fun filterModuleByNeedToCreateBase(it: VfModule):Boolean {
+ private fun vfModulesForChildrenJobs(vfModules: List<VfModule>): List<VfModule> =
+ vfModules
+ .filter { filterModuleByNeedToCreateBase(it) }
+ .map { childVfModuleWithVnfRegionAndTenant(it) }
+
+ internal fun childVfModuleWithVnfRegionAndTenant(vfModule: VfModule): VfModule {
+ if (featureManager.isNotActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)) {
+ return vfModule
+ }
+
+ val vnfLcpCloudRegionId = getRequest().lcpCloudRegionId
+ val vnfTenantId = getRequest().tenantId
+ return vfModule.cloneWith(vnfLcpCloudRegionId, vnfTenantId)
+ }
+
+ private fun filterModuleByNeedToCreateBase(vfModule: VfModule): Boolean {
return needToCreateBaseModule ==
- commandUtils.isVfModuleBaseModule(
- serviceModelInfoFromRequest().modelVersionId,
- it.modelInfo.modelVersionId)
+ commandUtils.isVfModuleBaseModule(
+ serviceModelInfoFromRequest().modelVersionId,
+ vfModule.modelInfo.modelVersionId)
}
override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan {
package org.onap.vid.model;
+import org.onap.logging.ref.slf4j.ONAPLogConstants.MDCs;
import org.slf4j.MDC;
-import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
-
/**
* The Class ExceptionResponse.
*/
public void setException(Exception exception) {
setException(exception.getClass().toString().replaceFirst("^.*[\\.$]", ""));
- setMessage(exception.getMessage() + " (Request id: " + MDC.get(MDC_KEY_REQUEST_ID) + ")");
+ setMessage(exception.getMessage() + " (Request id: " + MDC.get(MDCs.REQUEST_ID) + ")");
}
/**
package org.onap.vid.model;
-public class ServiceInstanceSearchResult {
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.vid.roles.WithPermissionPropertiesOwningEntity;
+import org.onap.vid.roles.WithPermissionPropertiesSubscriberAndServiceType;
+
+public class ServiceInstanceSearchResult
+ implements WithPermissionPropertiesSubscriberAndServiceType, WithPermissionPropertiesOwningEntity {
+
+ private final String SUBSCRIBER_ID_FRONTEND_ALIAS = "globalCustomerId";
private String serviceInstanceId;
- private String globalCustomerId;
+ private String subscriberId;
private String serviceType;
private String aaiModelVersionId;
+ private String owningEntityId;
+
private boolean isPermitted;
public ServiceInstanceSearchResult(){
-
}
- public ServiceInstanceSearchResult(String serviceInstanceId, String globalCustomerId, String serviceType,
- String serviceInstanceName, String subscriberName, String aaiModelInvariantId,
- String aaiModelVersionId, boolean isPermitted) {
+
+ public ServiceInstanceSearchResult(String serviceInstanceId, String subscriberId, String serviceType,
+ String serviceInstanceName, String subscriberName, String aaiModelInvariantId,
+ String aaiModelVersionId, String owningEntityId, boolean isPermitted) {
this.serviceInstanceId = serviceInstanceId;
- this.globalCustomerId = globalCustomerId;
+ this.subscriberId = subscriberId;
this.serviceType = serviceType;
this.serviceInstanceName = serviceInstanceName;
this.subscriberName = subscriberName;
this.aaiModelInvariantId = aaiModelInvariantId;
this.aaiModelVersionId = aaiModelVersionId;
+ this.owningEntityId = owningEntityId;
this.isPermitted = isPermitted;
}
this.serviceInstanceId = serviceInstanceId;
}
- public String getGlobalCustomerId() {
- return globalCustomerId;
+ @Override
+ @JsonProperty(SUBSCRIBER_ID_FRONTEND_ALIAS)
+ public String getSubscriberId() {
+ return subscriberId;
}
- public void setGlobalCustomerId(String globalCustomerId) {
- this.globalCustomerId = globalCustomerId;
+ public void setSubscriberId(String subscriberId) {
+ this.subscriberId = subscriberId;
}
+ @Override
public String getServiceType() {
return serviceType;
}
this.aaiModelVersionId = aaiModelVersionId;
}
+ @Override
+ public String getOwningEntityId() {
+ return owningEntityId;
+ }
+
+ public void setOwningEntityId(String owningEntityId) {
+ this.owningEntityId = owningEntityId;
+ }
+
public boolean getIsPermitted() {
return isPermitted;
}
}
@Override
- public boolean equals(Object other){
- if (other instanceof ServiceInstanceSearchResult) {
- ServiceInstanceSearchResult serviceInstanceSearchResultOther = (ServiceInstanceSearchResult) other;
- if (this.getServiceInstanceId().equals(serviceInstanceSearchResultOther.getServiceInstanceId())) {
- return true;
- }
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
}
- return false;
+ ServiceInstanceSearchResult that = (ServiceInstanceSearchResult) o;
+
+ return StringUtils.equals(serviceInstanceId, that.serviceInstanceId);
}
@Override
public int hashCode() {
- int result = 17;
- result = 31 * result + serviceInstanceId.hashCode();
- return result;
+ return serviceInstanceId != null ? serviceInstanceId.hashCode() : 0;
}
}
package org.onap.vid.model.serviceInstantiation;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobType;
import org.onap.vid.model.Action;
import org.onap.vid.mso.model.ModelInfo;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
public abstract class BaseResource implements JobAdapter.AsyncJobRequest {
protected String instanceId;
protected Integer position;
+ @JsonInclude(NON_NULL)
+ protected String originalName; //not used at backend, but stored for fronted
+
private static final Map<String, Action> actionStingToEnumMap = ImmutableMap.<String, Action>builder()
.put("Delete", Action.Delete)
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
this.modelInfo = modelInfo;
this.modelInfo.setModelType(getModelType());
this.rollbackOnFailure = rollbackOnFailure;
this.isFailed = isFailed!= null ? isFailed: false;
this.statusMessage = statusMessage;
this.position = position;
+ this.originalName = originalName;
}
private Action actionStringToEnum(String actionAsString) {
this.position = position;
}
+ public String getOriginalName() {
+ return originalName;
+ }
+
@JsonIgnore
public abstract Collection<? extends BaseResource> getChildren();
package org.onap.vid.model.serviceInstantiation;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.onap.vid.job.JobAdapter;
-import org.onap.vid.job.JobType;
-import org.onap.vid.mso.model.ModelInfo;
-
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import org.onap.vid.job.JobAdapter;
+import org.onap.vid.job.JobType;
+import org.onap.vid.mso.model.ModelInfo;
public class InstanceGroup extends BaseResource implements JobAdapter.AsyncJobRequest {
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, null, null, null, null, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.vnfGroupMembers = vnfGroupMembers;
}
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(new ModelInfo(), null, action, null, null, null, null, false, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
}
@Override
package org.onap.vid.model.serviceInstantiation;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.onap.vid.job.JobAdapter;
-import org.onap.vid.job.JobType;
-import org.onap.vid.mso.model.ModelInfo;
-
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.onap.vid.job.JobAdapter;
+import org.onap.vid.job.JobType;
+import org.onap.vid.mso.model.ModelInfo;
public class Network extends BaseResource implements JobAdapter.AsyncJobRequest {
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.productFamilyId = productFamilyId;
this.platformName = platformName;
this.lineOfBusiness = lineOfBusiness;
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("vidNotions") VidNotions vidNotions) {
+ @JsonProperty("vidNotions") VidNotions vidNotions,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- null);
+ null, originalName);
this.owningEntityId = owningEntityId;
this.owningEntityName = owningEntityName;
this.projectName = projectName;
baseService.isRollbackOnFailure(), baseService.isALaCarte(), baseService.getTestApi(),
baseService.getInstanceId(), Objects.toString(baseService.getAction(), null),
baseService.getTrackById(), baseService.getIsFailed(), baseService.getStatusMessage(),
- baseService.getVidNotions()
+ baseService.getVidNotions(),
+ baseService.getOriginalName()
);
this.existingVNFCounterMap = vnfCounterMap;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobType;
import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
/**
* The Class VfModule.
@JsonInclude(NON_NULL) @JsonProperty("volumeGroupName") private final String volumeGroupInstanceName;
@JsonInclude(NON_NULL) @JsonProperty("sdncPreLoad") private Boolean usePreload;
- private Map<String, String> supplementaryParams;
+ private List<UserParamNameAndValue> supplementaryParams;
@JsonInclude(NON_NULL)
private final Boolean retainVolumeGroups;
@JsonProperty("legacyRegion") String legacyRegion,
@JsonProperty("tenantId") String tenantId,
@JsonProperty("instanceParams") List<Map<String, String>> instanceParams,
- @JsonProperty("supplementaryFileContent") Map<String, String> supplementaryParams,
+ @JsonProperty("supplementaryFileContent") List<UserParamNameAndValue> supplementaryParams,
@JsonProperty("rollbackOnFailure") boolean rollbackOnFailure,
@JsonProperty("sdncPreLoad") @JsonAlias("usePreload") Boolean usePreload,
@JsonProperty("instanceId") String instanceId,
@JsonProperty("statusMessage") String statusMessage,
@Nullable @JsonProperty("retainAssignments") Boolean retainAssignments,
@Nullable @JsonProperty("retainVolumeGroups") Boolean retainVolumeGroups,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.volumeGroupInstanceName = volumeGroupInstanceName;
this.usePreload = usePreload;
this.supplementaryParams = supplementaryParams;
return usePreload;
}
- public Map<String, String> getSupplementaryParams() {
+ public List<UserParamNameAndValue> getSupplementaryParams() {
return supplementaryParams;
}
this.getStatusMessage(),
this.isRetainAssignments(),
this.isRetainVolumeGroups(),
- this.getPosition());
+ this.getPosition(),
+ this.getOriginalName()
+ );
+ }
+
+ public VfModule cloneWith(String lcpCloudRegionId, String tenantId) {
+ return new VfModule(
+ this.getModelInfo(),
+ this.getInstanceName(),
+ this.getVolumeGroupInstanceName(),
+ this.getAction().toString(),
+ lcpCloudRegionId,
+ lcpCloudRegionId,
+ tenantId,
+ this.getInstanceParams(),
+ this.getSupplementaryParams(),
+ this.isRollbackOnFailure(),
+ this.isUsePreload(),
+ this.getInstanceId(),
+ this.getTrackById(),
+ this.getIsFailed(),
+ this.getStatusMessage(),
+ this.isRetainAssignments(),
+ this.isRetainVolumeGroups(),
+ this.getPosition(),
+ this.getOriginalName()
+ );
}
}
\ No newline at end of file
package org.onap.vid.model.serviceInstantiation;
+import static java.util.stream.Collectors.toList;
+
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobType;
import org.onap.vid.mso.model.ModelInfo;
-import java.util.*;
-
-import static java.util.stream.Collectors.toList;
-
/**
* The Class VNF.
*/
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.productFamilyId = productFamilyId;
this.platformName = platformName;
this.lineOfBusiness = lineOfBusiness;
package org.onap.vid.mso;
+import static org.apache.commons.lang3.StringUtils.firstNonBlank;
+import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
-import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
import io.joshworks.restclient.http.HttpResponse;
import java.io.IOException;
-import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.onap.vid.exceptions.GenericUncheckedException;
public class MsoUtil {
}
public static String formatExceptionAdditionalInfo(int statusCode, String msoResponse) {
- String errorMsg = "Http Code:" + statusCode;
- if (!StringUtils.isEmpty(msoResponse)) {
- String filteredJson;
- try {
- filteredJson = StringUtils.defaultIfEmpty(
- JACKSON_OBJECT_MAPPER.readTree(msoResponse).path("serviceException").toString().replaceAll("[\\{\\}]","") ,
- msoResponse
- );
- } catch (JsonParseException e) {
- filteredJson = msoResponse;
- } catch (IOException e) {
- throw new GenericUncheckedException(e);
- }
+ final String errorMsg = "Http Code:" + statusCode;
+
+ if (isEmpty(msoResponse)) {
+ return errorMsg;
+ }
+
+ try {
+ JsonNode jsonNode = JACKSON_OBJECT_MAPPER.readTree(msoResponse);
- errorMsg = errorMsg + ", " + filteredJson;
+ return errorMsg + ", " + firstNonBlank(
+ removeBraces(jsonNode.get("serviceException")),
+ removeBraces(jsonNode.path("requestError").get("serviceException")),
+ msoResponse
+ );
+
+ } catch (Exception e) {
+ return errorMsg + ", " + msoResponse;
}
- return errorMsg;
+ }
+
+ private static String removeBraces(JsonNode jsonNode) {
+ if (jsonNode == null || jsonNode.isMissingNode()) {
+ return null;
+ }
+
+ return jsonNode.toString().replaceAll("[\\{\\}]", "");
}
}
package org.onap.vid.mso.model;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.onap.vid.mso.rest.SubscriberInfo;
-
import java.util.List;
import java.util.Map;
-
-import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY;
-import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+import java.util.Objects;
+import org.onap.vid.mso.rest.SubscriberInfo;
public class ServiceInstantiationRequestDetails {
private final String name;
private final String value;
- public UserParamNameAndValue(String name, String value) {
+ @JsonCreator
+ public UserParamNameAndValue(
+ @JsonProperty("name") String name,
+ @JsonProperty("value") String value
+ ) {
this.name = name;
this.value = value;
}
public String getValue() {
return value;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof UserParamNameAndValue)) {
+ return false;
+ }
+ UserParamNameAndValue that = (UserParamNameAndValue) o;
+ return Objects.equals(getName(), that.getName()) &&
+ Objects.equals(getValue(), that.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getName(), getValue());
+ }
}
public static class HomingSolution implements UserParamTypes {
open class RequestParametersVfModuleOrVolumeGroup internal constructor(
userParams: List<UserParamTypes>,
- @get:JsonInclude(NON_NULL) val isUsePreload: Boolean?,
+ val isUsePreload: Boolean,
testApi: String?
) : BaseResourceInstantiationRequestDetails.RequestParameters(userParams, testApi)
userParams: List<UserParamTypes>,
usePreload: Boolean?,
testApi: String?
-) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload, testApi)
+) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload.orFalse(), testApi)
class RequestParametersVfModuleUpgrade(
userParams: List<UserParamTypes>,
testApi: String?,
@get:JsonInclude(NON_NULL) val retainAssignments: Boolean?,
@get:JsonInclude(NON_NULL) val rebuildVolumeGroups: Boolean?
-) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload, testApi)
+) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload.orFalse(), testApi)
class UserParamMap<K, V> : HashMap<K, V>(), UserParamTypes, MutableMap<K, V>
+private fun Boolean?.orFalse(): Boolean = this ?: false
--- /dev/null
+package org.onap.vid.properties
+
+import org.apache.commons.io.filefilter.WildcardFileFilter
+import org.springframework.web.context.request.RequestContextHolder.getRequestAttributes
+import org.springframework.web.context.request.ServletRequestAttributes
+import org.togglz.core.Feature
+import org.togglz.core.manager.FeatureManager
+import org.togglz.core.manager.FeatureManagerBuilder
+import org.togglz.core.repository.file.FileBasedStateRepository
+import java.io.File
+import java.io.FilenameFilter
+import javax.servlet.ServletContext
+import javax.servlet.http.HttpServletRequest
+
+
+private const val SLOW_RELOAD = 60_000
+private const val COOKIE_NAME = "features.set"
+
+class FeatureSetsManager(
+ private val defaultManager: FeatureManager,
+ private val nameProvider: AlternativeFeatureSetNameProvider,
+ private val servletContext: ServletContext
+) : FeatureManager by defaultManager {
+
+ override fun isActive(feature: Feature?): Boolean {
+ return resolvedFeatureManager().isActive(feature)
+ }
+
+ private fun resolvedFeatureManager(): FeatureManager {
+ return when (val alternativeFeatureSetName = nameProvider.alternativeFeatureSetName) {
+ null -> defaultManager
+ else -> allFeatureManagers.getValue(alternativeFeatureSetName)
+ }
+ }
+
+ internal val allFeatureManagers: Map<String, FeatureManager> by lazy {
+ allFeatureSetFiles().associateBy(
+ { it.name },
+ { newFeatureManager(it) }
+ ).withDefault { allFeaturesOff }
+ }
+
+ private val allFeaturesOff =
+ FeatureManagerBuilder().featureEnum(Features::class.java).build()
+
+ private fun newFeatureManager(file: File): FeatureManager {
+ return FeatureManagerBuilder()
+ .featureEnum(Features::class.java)
+ .stateRepository(FileBasedStateRepository(file, SLOW_RELOAD))
+ .build()
+ }
+
+ private fun allFeatureSetFiles(): Array<File> {
+ val dir = File(servletContext.getRealPath("/WEB-INF/conf/"))
+ val fileFilter: FilenameFilter = WildcardFileFilter("*.features.properties")
+
+ return dir.listFiles(fileFilter) ?: emptyArray()
+ }
+}
+
+interface AlternativeFeatureSetNameProvider {
+ val alternativeFeatureSetName: String?
+}
+
+class AlternativeFeatureSetNameFromCookie: AlternativeFeatureSetNameProvider {
+ override val alternativeFeatureSetName: String?
+ get() = valueFromCookie(currentHttpRequest())
+
+ internal fun valueFromCookie(httpServletRequest: HttpServletRequest?): String? {
+ return httpServletRequest
+ ?.cookies
+ ?.firstOrNull { it.name == COOKIE_NAME }
+ ?.value
+ }
+
+ internal fun currentHttpRequest(): HttpServletRequest? {
+ return when (val requestAttributes = getRequestAttributes()) {
+ is ServletRequestAttributes -> requestAttributes.request
+ else -> null
+ }
+ }
+}
FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
FLAG_2004_INSTANTIATION_STATUS_FILTER,
FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
- FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER,
FLAG_2004_INSTANTIATION_TEMPLATES_POPUP,
+ FLAG_2006_VFM_SDNC_PRELOAD_FILES,
FLAG_2002_UNLIMITED_MAX,
+ FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO,
+ FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY,
+ FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF,
+
;
package org.onap.vid.properties;
+import java.io.File;
+import javax.servlet.ServletContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.togglz.core.repository.file.FileBasedStateRepository;
import org.togglz.spring.listener.TogglzApplicationContextBinderApplicationListener;
-import javax.servlet.ServletContext;
-import java.io.File;
-
@Configuration
public class FeaturesTogglingConfiguration {
@Bean
filename = StringUtils.trimToNull(filename);
- return new FeatureManagerBuilder()
+ return new FeatureSetsManager(
+ new FeatureManagerBuilder()
.featureEnum(Features.class)
.stateRepository(new FileBasedStateRepository(
- new File(filename.startsWith("/")? filename : servletContext.getRealPath("/WEB-INF/conf/" + filename))
+ new File(filename.startsWith("/") ? filename : servletContext.getRealPath("/WEB-INF/conf/" + filename))
))
- .build();
+ .build(), new AlternativeFeatureSetNameFromCookie(), servletContext
+ );
}
}
}
@Override
- public boolean isSubscriberPermitted(String subscriberName) {
+ public boolean isSubscriberPermitted(String subscriberId) {
return true;
}
@Override
- public boolean isServicePermitted(String subscriberName, String serviceType) {
+ public boolean isServicePermitted(WithPermissionProperties permissionProperties) {
return true;
}
@Override
- public boolean isTenantPermitted(String globalCustomerId, String serviceType, String tenantName) {
+ public boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName) {
return true;
}
}
--- /dev/null
+package org.onap.vid.roles
+
+import org.onap.vid.aai.ServiceSubscription
+
+
+interface WithPermissionProperties
+
+interface WithPermissionPropertiesSubscriberAndServiceType: WithPermissionProperties {
+ val subscriberId: String?
+ val serviceType: String?
+}
+
+interface WithPermissionPropertiesOwningEntity: WithPermissionProperties {
+ val owningEntityId: String?
+}
+
+
+data class AllPermissionProperties(
+ override val subscriberId: String?,
+ override val serviceType: String?,
+ override val owningEntityId: String?
+): WithPermissionPropertiesOwningEntity, WithPermissionPropertiesSubscriberAndServiceType
+
+data class PermissionPropertiesOwningEntity(
+ override val owningEntityId: String?
+): WithPermissionPropertiesOwningEntity
+
+data class PermissionPropertiesSubscriberAndServiceType(
+ override val subscriberId: String?,
+ override val serviceType: String?
+) : WithPermissionPropertiesSubscriberAndServiceType {
+ constructor(serviceSubscription: ServiceSubscription, subscriberId: String?) : this(subscriberId, serviceSubscription.serviceType)
+}
+
package org.onap.vid.roles;
-/**
- * Created by Oren on 7/1/17.
- */
-
public class Role {
- private EcompRole ecompRole;
+ private final EcompRole ecompRole;
+
+ private final String subscriberId;
- private String subscribeName;
+ private final String serviceType;
- private String serviceType;
+ private final String tenant;
- private String tenant;
+ private final String owningEntityId;
- public Role(EcompRole ecompRole, String subscribeName, String serviceType, String tenant) {
+ public Role(EcompRole ecompRole, String subscriberId, String serviceType, String tenant, String owningEntityId) {
this.ecompRole = ecompRole;
- this.subscribeName = subscribeName;
+ this.subscriberId = subscriberId;
this.serviceType = serviceType;
this.tenant = tenant;
+ this.owningEntityId = owningEntityId;
}
public EcompRole getEcompRole() {
return ecompRole;
}
-
- public String getSubscribeName() {
- return subscribeName;
- }
-
- public void setSubscribeName(String subscribeName) {
- this.subscribeName = subscribeName;
+ public String getSubscriberId() {
+ return subscriberId;
}
public String getServiceType() {
return serviceType;
}
-
public String getTenant() {
return tenant;
}
-
+ public String getOwningEntityId() {
+ return owningEntityId;
+ }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-
-/**
- * Created by Oren on 7/1/17.
- */
-
@Component
public class RoleProvider {
private Function<HttpServletRequest, Integer> getUserIdFunction;
private Function<HttpServletRequest, Map> getRolesFunction;
+ private final RoleValidatorFactory roleValidatorFactory;
@Autowired
- public RoleProvider(AaiService aaiService) {
+ public RoleProvider(AaiService aaiService, RoleValidatorFactory roleValidatorFactory) {
this.aaiService=aaiService;
+ this.roleValidatorFactory = roleValidatorFactory;
getUserIdFunction = UserUtils::getUserId;
getRolesFunction = UserUtils::getRoles;
}
- RoleProvider(AaiService aaiService, Function<HttpServletRequest, Integer> getUserIdFunction, Function<HttpServletRequest, Map> getRolesFunction) {
+ RoleProvider(AaiService aaiService, RoleValidatorFactory roleValidatorFactory,
+ Function<HttpServletRequest, Integer> getUserIdFunction, Function<HttpServletRequest, Map> getRolesFunction) {
this.aaiService = aaiService;
+ this.roleValidatorFactory = roleValidatorFactory;
this.getRolesFunction = getRolesFunction;
this.getUserIdFunction = getUserIdFunction;
}
public Role createRoleFromStringArr(String[] roleParts, String rolePrefix) throws RoleParsingException {
String globalCustomerID = replaceSubscriberNameToGlobalCustomerID(roleParts[0], rolePrefix);
+ String owningEntityId = translateOwningEntityNameToOwningEntityId(roleParts[0]);
+
try {
if (roleParts.length > 2) {
- return new Role(EcompRole.READ, globalCustomerID, roleParts[1], roleParts[2]);
+ return new Role(EcompRole.READ, globalCustomerID, roleParts[1], roleParts[2], owningEntityId);
} else {
- return new Role(EcompRole.READ, globalCustomerID, roleParts[1], null);
+ return new Role(EcompRole.READ, globalCustomerID, roleParts[1], null, owningEntityId);
}
} catch (ArrayIndexOutOfBoundsException e) {
if (roleParts.length > 0)
}
+ private String translateOwningEntityNameToOwningEntityId(String owningEntityName) {
+ return owningEntityName; // TODO: translate to id
+ }
+
public RoleValidator getUserRolesValidator(HttpServletRequest request) {
- return RoleValidator.by(getUserRoles(request));
+ return roleValidatorFactory.by(getUserRoles(request));
}
}
package org.onap.vid.roles;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.onap.portalsdk.core.util.SystemProperties;
-
public interface RoleValidator {
- static RoleValidator by(List<Role> roles) {
- final boolean disableRoles = StringUtils.equals(SystemProperties.getProperty("role_management_activated"), "false");
- return by(roles, disableRoles);
- }
-
- static RoleValidator by(List<Role> roles, boolean disableRoles) {
- return disableRoles
- ? new AlwaysValidRoleValidator()
- : new RoleValidatorByRoles(roles);
- }
-
- boolean isSubscriberPermitted(String subscriberName);
+ boolean isSubscriberPermitted(String subscriberId);
- boolean isServicePermitted(String subscriberName, String serviceType);
+ boolean isServicePermitted(WithPermissionProperties serviceInstanceSearchResult);
- boolean isTenantPermitted(String globalCustomerId, String serviceType, String tenantName);
+ boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName);
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+
+public class RoleValidatorByOwningEntity implements RoleValidator{
+
+ private final List<Role> userRoles;
+
+ RoleValidatorByOwningEntity(List<Role> roles) {
+ this.userRoles = roles;
+ }
+
+ private boolean isOwningEntityIdPermitted(String owningEntityId) {
+ if (StringUtils.isEmpty(owningEntityId)) {
+ return false;
+ }
+
+ return userRoles.stream().anyMatch(userRole ->
+ StringUtils.equals(userRole.getOwningEntityId(), owningEntityId)
+ );
+ }
+
+ @Override
+ public boolean isSubscriberPermitted(String subscriberId) {
+ return false;
+ }
+
+ @Override
+ public boolean isServicePermitted(WithPermissionProperties permissionProperties) {
+ if (permissionProperties instanceof WithPermissionPropertiesOwningEntity) {
+ String owningEntityId = ((WithPermissionPropertiesOwningEntity) permissionProperties).getOwningEntityId();
+ return isOwningEntityIdPermitted(owningEntityId);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName) {
+ return false;
+ }
+}
package org.onap.vid.roles;
import java.util.List;
-import java.util.Map;
-import org.onap.vid.mso.rest.RequestDetails;
+import org.apache.commons.lang3.StringUtils;
-public class RoleValidatorByRoles implements RoleValidator {
+public class RoleValidatorBySubscriberAndServiceType implements RoleValidator {
private final List<Role> userRoles;
- RoleValidatorByRoles(List<Role> roles) {
+ RoleValidatorBySubscriberAndServiceType(List<Role> roles) {
this.userRoles = roles;
}
@Override
- public boolean isSubscriberPermitted(String subscriberName) {
+ public boolean isSubscriberPermitted(String subscriberId) {
for (Role role : userRoles) {
- if (role.getSubscribeName().equals(subscriberName)) {
+ if (role.getSubscriberId().equals(subscriberId)) {
return true;
}
}
}
@Override
- public boolean isServicePermitted(String subscriberName, String serviceType) {
- for (Role role : userRoles) {
- if (role.getSubscribeName().equals(subscriberName) && role.getServiceType().equals(serviceType)) {
- return true;
- }
+ public boolean isServicePermitted(WithPermissionProperties permissionProperties) {
+ if (permissionProperties instanceof WithPermissionPropertiesSubscriberAndServiceType) {
+ return isServicePermitted(
+ (WithPermissionPropertiesSubscriberAndServiceType) permissionProperties
+ );
}
return false;
}
+ private boolean isServicePermitted(WithPermissionPropertiesSubscriberAndServiceType permissionProperties) {
+ return userRoles.stream().anyMatch(userRole ->
+ StringUtils.equals(userRole.getSubscriberId(), permissionProperties.getSubscriberId())
+ && StringUtils.equals(userRole.getServiceType(), permissionProperties.getServiceType())
+ );
+ }
+
@Override
- public boolean isTenantPermitted(String globalCustomerId, String serviceType, String tenantName) {
+ public boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName) {
for (Role role : userRoles) {
- if (role.getSubscribeName().equals(globalCustomerId)
+ if (role.getSubscriberId().equals(subscriberId)
&& role.getServiceType().equals(serviceType)
&& (role.getTenant() == null || role.getTenant().equalsIgnoreCase(tenantName))) {
return true;
return false;
}
- boolean isMsoRequestValid(RequestDetails msoRequest) {
- try {
- String globalSubscriberIdRequested = (String) ((Map) ((Map) msoRequest.getAdditionalProperties()
- .get("requestDetails")).get("subscriberInfo")).get("globalSubscriberId");
- String serviceType = (String) ((Map) ((Map) msoRequest.getAdditionalProperties().get("requestDetails"))
- .get("requestParameters")).get("subscriptionServiceType");
- return isServicePermitted(globalSubscriberIdRequested, serviceType);
- } catch (Exception e) {
- //Until we'll get the exact information regarding the tenants and the global customer id, we'll return true on unknown requests to mso
- return true;
- }
- }
-
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.properties.Features;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.togglz.core.manager.FeatureManager;
+
+@Component
+public class RoleValidatorFactory {
+ private final FeatureManager featureManager;
+
+ @Autowired
+ public RoleValidatorFactory(FeatureManager featureManager) {
+ this.featureManager = featureManager;
+ }
+
+
+ public RoleValidator by(List<Role> roles) {
+ final boolean disableRoles = StringUtils
+ .equals(SystemProperties.getProperty("role_management_activated"), "false");
+ return by(roles, disableRoles);
+ }
+
+ public RoleValidator by(List<Role> roles, boolean disableRoles) {
+
+ if(disableRoles) {
+ return new AlwaysValidRoleValidator();
+ }
+ else if (featureManager.isActive(Features.FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY)){
+ return new RoleValidatorsComposer(
+ new RoleValidatorBySubscriberAndServiceType(roles),
+ new RoleValidatorByOwningEntity(roles)
+ );
+ }
+ else {
+ return new RoleValidatorBySubscriberAndServiceType(roles);
+ }
+ }
+}
--- /dev/null
+package org.onap.vid.roles
+
+class RoleValidatorsComposer(private vararg val roleValidators: RoleValidator) : RoleValidator {
+
+ constructor(roleValidators: Collection<RoleValidator>) : this(*roleValidators.toTypedArray())
+
+ override fun isServicePermitted(p: WithPermissionProperties): Boolean =
+ roleValidators.any { it.isServicePermitted(p) }
+
+ override fun isSubscriberPermitted(subscriberId: String?): Boolean =
+ roleValidators.any { it.isSubscriberPermitted(subscriberId) }
+
+ override fun isTenantPermitted(subscriberId: String?, serviceType: String?, tenantName: String?): Boolean =
+ roleValidators.any { it.isTenantPermitted(subscriberId, serviceType, tenantName) }
+
+}
package org.onap.vid.services;
+import static java.util.Collections.emptyList;
+import static org.apache.commons.collections4.ListUtils.emptyIfNull;
import static org.onap.vid.aai.AaiClient.QUERY_FORMAT_RESOURCE;
import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.validation.constraints.NotNull;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.onap.vid.model.aaiTree.RelatedVnf;
import org.onap.vid.model.aaiTree.VpnBinding;
import org.onap.vid.model.aaiTree.VpnBindingKt;
+import org.onap.vid.roles.PermissionPropertiesSubscriberAndServiceType;
import org.onap.vid.roles.RoleValidator;
import org.onap.vid.utils.Intersection;
import org.onap.vid.utils.Logging;
private static final String SERVICE_INSTANCE_ID = "service-instance.service-instance-id";
private static final String SERVICE_TYPE = "service-subscription.service-type";
private static final String CUSTOMER_ID = "customer.global-customer-id";
+ private static final String OWNING_ENTITY_ID = "owning-entity.owning-entity-id";
private static final String SERVICE_INSTANCE_NAME = "service-instance.service-instance-name";
private static final String TENANT_NODE_TYPE = "tenant";
private static final String CLOUD_REGION_NODE_TYPE = "cloud-region";
}
}
- private List<ServiceInstanceSearchResult> getServicesByOwningEntityId(List<String> owningEntities, RoleValidator roleValidator) {
+ List<ServiceInstanceSearchResult> getServicesByOwningEntityId(List<String> owningEntities, RoleValidator roleValidator) {
AaiResponse<OwningEntityResponse> owningEntityResponse = aaiClient.getServicesByOwningEntityId(owningEntities);
List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
if (owningEntityResponse.getT() != null) {
for (OwningEntity owningEntity : owningEntityResponse.getT().getOwningEntity()) {
if (owningEntity.getRelationshipList() != null) {
- serviceInstanceSearchResultList = convertRelationshipToSearchResult(owningEntity, serviceInstanceSearchResultList, roleValidator);
+ serviceInstanceSearchResultList.addAll(convertRelationshipToSearchResult(owningEntity, roleValidator, owningEntity.getOwningEntityId()));
}
}
}
return serviceInstanceSearchResultList;
}
- private List<ServiceInstanceSearchResult> getServicesByProjectNames(List<String> projectNames, RoleValidator roleValidator) {
+ List<ServiceInstanceSearchResult> getServicesByProjectNames(List<String> projectNames, RoleValidator roleValidator) {
AaiResponse<ProjectResponse> projectByIdResponse = aaiClient.getServicesByProjectNames(projectNames);
List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
if (projectByIdResponse.getT() != null) {
for (Project project : projectByIdResponse.getT().getProject()) {
if (project.getRelationshipList() != null) {
- serviceInstanceSearchResultList = convertRelationshipToSearchResult(project, serviceInstanceSearchResultList, roleValidator);
+ serviceInstanceSearchResultList.addAll(convertRelationshipToSearchResult(project, roleValidator, null));
}
}
}
return serviceInstanceSearchResultList;
}
- private List<ServiceInstanceSearchResult> convertRelationshipToSearchResult(AaiRelationResponse owningEntityResponse, List<ServiceInstanceSearchResult> serviceInstanceSearchResultList, RoleValidator roleValidator) {
- if (owningEntityResponse.getRelationshipList().getRelationship() != null) {
- List<Relationship> relationshipList = owningEntityResponse.getRelationshipList().getRelationship();
+ private List<ServiceInstanceSearchResult> convertRelationshipToSearchResult(AaiRelationResponse aaiRelationResponse, RoleValidator roleValidator, String owningEntityId) {
+ List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
+ if (aaiRelationResponse.getRelationshipList().getRelationship() != null) {
+ List<Relationship> relationshipList = aaiRelationResponse.getRelationshipList().getRelationship();
for (Relationship relationship : relationshipList) {
ServiceInstanceSearchResult serviceInstanceSearchResult = new ServiceInstanceSearchResult();
extractRelationshipData(relationship, serviceInstanceSearchResult, roleValidator);
extractRelatedToProperty(relationship, serviceInstanceSearchResult);
+ serviceInstanceSearchResult.setOwningEntityId(owningEntityId);
+ serviceInstanceSearchResult.setIsPermitted(roleValidator.isServicePermitted(serviceInstanceSearchResult));
serviceInstanceSearchResultList.add(serviceInstanceSearchResult);
}
}
} else if (key.equals(SERVICE_TYPE)) {
serviceInstanceSearchResult.setServiceType(relationshipData.getRelationshipValue());
} else if (key.equals(CUSTOMER_ID)) {
- serviceInstanceSearchResult.setGlobalCustomerId(relationshipData.getRelationshipValue());
+ serviceInstanceSearchResult.setSubscriberId(relationshipData.getRelationshipValue());
}
}
-
- boolean isPermitted = roleValidator.isServicePermitted(serviceInstanceSearchResult.getSubscriberName(), serviceInstanceSearchResult.getServiceType());
- serviceInstanceSearchResult.setIsPermitted(isPermitted);
}
}
@Override
public AaiResponse getSubscriberData(String subscriberId, RoleValidator roleValidator, boolean omitServiceInstances) {
AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId, omitServiceInstances);
- String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
for (ServiceSubscription serviceSubscription : subscriberResponse.getT().serviceSubscriptions.serviceSubscription) {
- String serviceType = serviceSubscription.serviceType;
- serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
+ serviceSubscription.isPermitted = roleValidator.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(serviceSubscription, subscriberResponse.getT().globalCustomerId));
}
return subscriberResponse;
private List<ServiceInstanceSearchResult> getServicesBySubscriber(String subscriberId, String instanceIdentifier, RoleValidator roleValidator) {
AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId, false);
- String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
String subscriberName = subscriberResponse.getT().subscriberName;
ServiceSubscriptions serviceSubscriptions = subscriberResponse.getT().serviceSubscriptions;
- return getSearchResultsForSubscriptions(serviceSubscriptions, subscriberId, instanceIdentifier, roleValidator, subscriberGlobalId, subscriberName);
-
+ return getSearchResultsForSubscriptions(serviceSubscriptions, subscriberId, instanceIdentifier, roleValidator, subscriberName);
}
- private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSubscriptions(ServiceSubscriptions serviceSubscriptions, String subscriberId, String instanceIdentifier, RoleValidator roleValidator, String subscriberGlobalId, String subscriberName) {
+ private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSubscriptions(
+ ServiceSubscriptions serviceSubscriptions, String subscriberId, String instanceIdentifier,
+ RoleValidator roleValidator, String subscriberName) {
ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
if (serviceSubscriptions != null) {
for (ServiceSubscription serviceSubscription : serviceSubscriptions.serviceSubscription) {
- String serviceType = serviceSubscription.serviceType;
- serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
- ArrayList<ServiceInstanceSearchResult> resultsForSubscription = getSearchResultsForSingleSubscription(serviceSubscription, subscriberId, instanceIdentifier, subscriberName, serviceType);
- results.addAll(resultsForSubscription);
+ serviceSubscription.isPermitted = roleValidator.isServicePermitted(new PermissionPropertiesSubscriberAndServiceType(serviceSubscription, subscriberId));
+ results.addAll(getSearchResultsForSingleSubscription(
+ serviceSubscription, subscriberId, instanceIdentifier, subscriberName,
+ serviceSubscription.serviceType, roleValidator)
+ );
}
}
return results;
}
- private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSingleSubscription(ServiceSubscription serviceSubscription, String subscriberId, String instanceIdentifier, String subscriberName, String serviceType) {
+ private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSingleSubscription(
+ ServiceSubscription serviceSubscription, String subscriberId, String instanceIdentifier, String subscriberName,
+ String serviceType, RoleValidator roleValidator) {
ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
if (serviceSubscription.serviceInstances != null) {
for (ServiceInstance serviceInstance : serviceSubscription.serviceInstances.serviceInstance) {
+
ServiceInstanceSearchResult serviceInstanceSearchResult =
- new ServiceInstanceSearchResult(serviceInstance.serviceInstanceId, subscriberId, serviceType, serviceInstance.serviceInstanceName,
- subscriberName, serviceInstance.modelInvariantId, serviceInstance.modelVersionId, serviceSubscription.isPermitted);
+ new ServiceInstanceSearchResult(serviceInstance.serviceInstanceId, subscriberId, serviceType,
+ serviceInstance.serviceInstanceName, subscriberName, serviceInstance.modelInvariantId,
+ serviceInstance.modelVersionId, relatedOwningEntityId(serviceInstance), false);
+
+ serviceInstanceSearchResult.setIsPermitted(roleValidator.isServicePermitted(serviceInstanceSearchResult));
if ((instanceIdentifier == null) || (serviceInstanceMatchesIdentifier(instanceIdentifier, serviceInstance))){
results.add(serviceInstanceSearchResult);
return results;
}
+ protected String relatedOwningEntityId(ServiceInstance serviceInstance) {
+ /*
+ For reference, consider the service-instance structure below. Method will null-safely extract the
+ `relationship-value` where `relationship-key` == `owning-entity.owning-entity-id`.
+
+ {
+ "service-instance-id": "5d521981-33be-4bb5-bb20-5616a9c52a5a",
+ ...
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "owning-entity",
+ "related-link": "/aai/v11/business/owning-entities/owning-entity/4d4ecf59-41f1-40d4-818d-885234680a42",
+ "relationship-data": [
+ {
+ "relationship-key": "owning-entity.owning-entity-id",
+ "relationship-value": "4d4ecf59-41f1-40d4-818d-885234680a42"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ */
+
+ Stream<RelationshipData> allRelationships =
+ Optional.ofNullable(serviceInstance.relationshipList)
+ .map(it -> it.getRelationship())
+ .map(it -> it.stream().flatMap(r -> emptyIfNull(r.getRelationDataList()).stream()))
+ .orElse(Stream.empty());
+
+ return allRelationships
+ .filter(r -> StringUtils.equals(r.getRelationshipKey(), OWNING_ENTITY_ID))
+ .map(it -> it.getRelationshipValue())
+ .findAny().orElse(null);
+ }
+
private boolean serviceInstanceMatchesIdentifier(String instanceIdentifier, ServiceInstance serviceInstance) {
return instanceIdentifier.equals(serviceInstance.serviceInstanceId) || instanceIdentifier.equals(serviceInstance.serviceInstanceName);
}
return aaiTree.stream().map(VpnBindingKt::from).collect(Collectors.toList());
} catch (ExceptionWithRequestInfo exception) {
if (Objects.equals(404, exception.getHttpCode())) {
- return Collections.emptyList();
+ return emptyList();
}
throw exception;
}
return aaiTree.stream().map(Network::from).collect(Collectors.toList());
} catch (ExceptionWithRequestInfo exception) {
if (Objects.equals(404, exception.getHttpCode())) {
- return Collections.emptyList();
+ return emptyList();
}
throw exception;
}
int bulkSize = request.getBulkSize();
UUID templateId = UUID.randomUUID();
for (int i = 0; i < bulkSize; i++) {
- ServiceInstantiation requestPerJob = prepareServiceToBeUnique(request);
+ ServiceInstantiation clonedServiceInstantiation = cloneServiceInstantiation(request);
+ ServiceInstantiation requestPerJob = prepareServiceToBeUnique(clonedServiceInstantiation);
+ requestPerJob = clearStatusFromRequest(requestPerJob);
ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
JobType jobType = getJobType(requestPerJob);
final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
@Override
public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
+ serviceInstantiation.setBulkSize(1);
+ return replaceAllTrackById(serviceInstantiation);
+ }
+ private<T extends BaseResource> T replaceAllTrackById(T resource) {
+ resource.setTrackById(UUID.randomUUID().toString());
+ resource.getChildren().forEach(this::replaceAllTrackById);
+ return resource;
+ }
+
+ private ServiceInstantiation cloneServiceInstantiation(ServiceInstantiation serviceInstantiation) {
try {
- ServiceInstantiation clonedServiceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
- JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
- clonedServiceInstantiation.setBulkSize(1);
- return replaceAllTrackById(clonedServiceInstantiation);
+ return JACKSON_OBJECT_MAPPER.readValue(
+ JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
} catch (IOException e) {
throw new GenericUncheckedException(e);
}
-
}
- private<T extends BaseResource> T replaceAllTrackById(T resource) {
- resource.setTrackById(UUID.randomUUID().toString());
- resource.getChildren().forEach(this::replaceAllTrackById);
+ <T extends BaseResource> T clearStatusFromRequest(T resource) {
+ resource.setIsFailed(false);
+ resource.setStatusMessage(null);
+ resource.getChildren().forEach(this::clearStatusFromRequest);
return resource;
}
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.toList;
+import java.util.Collection;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import javax.inject.Inject;
+import org.jetbrains.annotations.NotNull;
+import org.onap.vid.asdc.beans.Service;
import org.onap.vid.dal.AsyncInstantiationRepository;
import org.onap.vid.model.ModelUtil;
import org.onap.vid.model.serviceInstantiation.BaseResource;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiationTemplate;
+import org.onap.vid.properties.Features;
import org.springframework.stereotype.Component;
+import org.togglz.core.manager.FeatureManager;
@Component
public class InstantiationTemplatesService {
private final ModelUtil modelUtil;
private final AsyncInstantiationRepository asyncInstantiationRepository;
+ private FeatureManager featureManager;
+
@Inject
public InstantiationTemplatesService(ModelUtil modelUtil,
- AsyncInstantiationRepository asyncInstantiationRepository) {
+ AsyncInstantiationRepository asyncInstantiationRepository,
+ FeatureManager featureManager) {
this.modelUtil = modelUtil;
this.asyncInstantiationRepository = asyncInstantiationRepository;
+ this.featureManager = featureManager;
}
public ServiceInstantiationTemplate getJobRequestAsTemplate(UUID jobId) {
);
}
+ public Collection<Service> setOnEachServiceIsTemplateExists(Collection<Service> services){
+ if (!featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)){
+ return unsetTemplateExistsToAllServices(services);
+
+ }
+
+ Set<String> serviceModelIdsFromDB = asyncInstantiationRepository.getAllTemplatesServiceModelIds();
+
+ return services.stream().map(it -> setTemplateExistForService(it, serviceModelIdsFromDB)).collect(toList());
+ }
+
+ @NotNull
+ protected Collection<Service> unsetTemplateExistsToAllServices(Collection<Service> services) {
+ services.forEach(it -> it.setIsInstantiationTemplateExists(false));
+ return services;
+ }
+
+ protected Service setTemplateExistForService(Service service, Set<String> serviceModelIdsFromDb) {
+ service.setIsInstantiationTemplateExists(serviceModelIdsFromDb.contains(service.getUuid()));
+ return service;
+ }
}
--- /dev/null
+package org.onap.vid.services
+
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue
+import org.onap.vid.mso.model.UserParamTypes
+
+class UserParamsContainer(instanceParams: Map<String, String>?, supplementaryParams: List<UserParamNameAndValue>?) {
+
+ val params:Map<String, String>
+
+ init {
+ params = aggregateAllInstanceParams(instanceParams, supplementaryParams)
+ }
+
+ private fun aggregateAllInstanceParams(
+ instanceParams: Map<String, String>?,
+ supplementaryParams: List<UserParamNameAndValue>?)
+ : Map<String, String> {
+ val instanceParamsSafe: Map<String, String> = instanceParams ?: emptyMap()
+ val supplementaryParamsSafe: Map<String, String> =
+ supplementaryParams?.associate{ it.name to it.value } ?: emptyMap()
+
+ return instanceParamsSafe.plus(supplementaryParamsSafe)
+ }
+
+ fun toALaCarte(): List<UserParamTypes> = toUserParamNameAndValue()
+
+ fun toMacroPre1806() : List<UserParamTypes> = toUserParamNameAndValue()
+
+ fun toMacroPost1806() : List<Map<String, String>> = toListOfMap()
+
+ private fun toUserParamNameAndValue(): List<UserParamNameAndValue> {
+ return params.map{UserParamNameAndValue(it.key, it.value)}.toList()
+ }
+
+ private fun toListOfMap() : List<Map<String, String>> {
+ return listOf(params)
+ }
+}
+
+
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.apache.commons.lang3.StringUtils.isEmpty
+import org.togglz.core.Feature
+import org.togglz.core.manager.FeatureManager
inline fun <reified E: Enum<E>> getEnumFromMapOfStrings(map: Map<String, Any>, key:String, defaultValue:E): E {
return java.lang.Enum.valueOf(E::class.java, (map.getOrDefault(key, defaultValue.name) as String))
}
+fun FeatureManager.isNotActive(feature: Feature) = this.isActive(feature).not()
+
@JvmField val JACKSON_OBJECT_MAPPER: ObjectMapper = jacksonObjectMapper()
class JoshworksJacksonObjectMapper: io.joshworks.restclient.http.mapper.ObjectMapper {
package org.onap.vid.utils;
+import static java.util.Collections.emptyMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCause;
import static org.apache.commons.lang3.exception.ExceptionUtils.getThrowableList;
<T> T withMDCInternal(Map<String, String> copyOfParentMDC, UncheckedThrowingSupplier<T> supplier) {
try {
- MDC.setContextMap(copyOfParentMDC);
+ MDC.setContextMap(defaultIfNull(copyOfParentMDC, emptyMap()));
return supplier.get();
} finally {
MDC.clear();
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function c(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function l(e){return void 0===e}function d(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function h(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function f(e,t){var n,s=[];for(n=0;n<e.length;++n)s.push(t(e[n],n));return s}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function _(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function y(e,t,n,s){return Ot(e,t,n,s,!0).utc()}function g(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function p(e){if(null==e._isValid){var t=g(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function v(e){var t=y(NaN);return null!=e?_(g(t),e):g(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var r=c.momentProperties=[];function w(e,t){var n,s,i;if(l(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),l(t._i)||(e._i=t._i),l(t._f)||(e._f=t._f),l(t._l)||(e._l=t._l),l(t._strict)||(e._strict=t._strict),l(t._tzm)||(e._tzm=t._tzm),l(t._isUTC)||(e._isUTC=t._isUTC),l(t._offset)||(e._offset=t._offset),l(t._pf)||(e._pf=g(t)),l(t._locale)||(e._locale=t._locale),0<r.length)for(n=0;n<r.length;n++)l(i=t[s=r[n]])||(e[s]=i);return e}var t=!1;function M(e){w(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,c.updateOffset(this),t=!1)}function S(e){return e instanceof M||null!=e&&null!=e._isAMomentObject}function D(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function k(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=D(t)),n}function a(e,t,n){var s,i=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),a=0;for(s=0;s<i;s++)(n&&e[s]!==t[s]||!n&&k(e[s])!==k(t[s]))&&a++;return a+r}function Y(e){!1===c.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return _(function(){if(null!=c.deprecationHandler&&c.deprecationHandler(null,i),a){for(var e,t=[],n=0;n<arguments.length;n++){if(e="","object"==typeof arguments[n]){for(var s in e+="\n["+n+"] ",arguments[0])e+=s+": "+arguments[0][s]+", ";e=e.slice(0,-2)}else e=arguments[n];t.push(e)}Y(i+"\nArguments: "+Array.prototype.slice.call(t).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,O={};function T(e,t){null!=c.deprecationHandler&&c.deprecationHandler(e,t),O[e]||(Y(t),O[e]=!0)}function x(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function b(e,t){var n,s=_({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},_(s[n],e[n]),_(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=_({},s[n]));return s}function P(e){null!=e&&this.set(e)}c.suppressDeprecationWarnings=!1,c.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};var W={};function H(e,t){var n=e.toLowerCase();W[n]=W[n+"s"]=W[t]=e}function R(e){return"string"==typeof e?W[e]||W[e.toLowerCase()]:void 0}function C(e){var t,n,s={};for(n in e)m(e,n)&&(t=R(n))&&(s[t]=e[n]);return s}var F={};function L(e,t){F[e]=t}function U(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,G=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},E={};function I(e,t,n,s){var i=s;"string"==typeof s&&(i=function(){return this[s]()}),e&&(E[e]=i),t&&(E[t[0]]=function(){return U(i.apply(this,arguments),t[1],t[2])}),n&&(E[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=j(t,e.localeData()),V[t]=V[t]||function(s){var e,i,t,r=s.match(N);for(e=0,i=r.length;e<i;e++)E[r[e]]?r[e]=E[r[e]]:r[e]=(t=r[e]).match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"");return function(e){var t,n="";for(t=0;t<i;t++)n+=x(r[t])?r[t].call(e,s):r[t];return n}}(t),V[t](e)):e.localeData().invalidDate()}function j(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(G.lastIndex=0;0<=n&&G.test(e);)e=e.replace(G,s),G.lastIndex=0,n-=1;return e}var Z=/\d/,z=/\d\d/,$=/\d{3}/,q=/\d{4}/,J=/[+-]?\d{6}/,B=/\d\d?/,Q=/\d\d\d\d?/,X=/\d\d\d\d\d\d?/,K=/\d{1,3}/,ee=/\d{1,4}/,te=/[+-]?\d{1,6}/,ne=/\d+/,se=/[+-]?\d+/,ie=/Z|[+-]\d\d:?\d\d/gi,re=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,oe={};function ue(e,n,s){oe[e]=x(n)?n:function(e,t){return e&&s?s:n}}function le(e,t){return m(oe,e)?oe[e](t._strict,t._locale):new RegExp(de(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function de(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var he={};function ce(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),d(n)&&(s=function(e,t){t[n]=k(e)}),t=0;t<e.length;t++)he[e[t]]=s}function fe(e,i){ce(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var me=0,_e=1,ye=2,ge=3,pe=4,ve=5,we=6,Me=7,Se=8;function De(e){return ke(e)?366:365}function ke(e){return e%4==0&&e%100!=0||e%400==0}I("Y",0,0,function(){var e=this.year();return e<=9999?""+e:"+"+e}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),H("year","y"),L("year",1),ue("Y",se),ue("YY",B,z),ue("YYYY",ee,q),ue("YYYYY",te,J),ue("YYYYYY",te,J),ce(["YYYYY","YYYYYY"],me),ce("YYYY",function(e,t){t[me]=2===e.length?c.parseTwoDigitYear(e):k(e)}),ce("YY",function(e,t){t[me]=c.parseTwoDigitYear(e)}),ce("Y",function(e,t){t[me]=parseInt(e,10)}),c.parseTwoDigitYear=function(e){return k(e)+(68<k(e)?1900:2e3)};var Ye,Oe=Te("FullYear",!0);function Te(t,n){return function(e){return null!=e?(be(this,t,e),c.updateOffset(this,n),this):xe(this,t)}}function xe(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function be(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&ke(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Pe(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function Pe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1===s?ke(e)?29:28:31-s%7%2}Ye=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t<this.length;++t)if(this[t]===e)return t;return-1},I("M",["MM",2],"Mo",function(){return this.month()+1}),I("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),I("MMMM",0,0,function(e){return this.localeData().months(this,e)}),H("month","M"),L("month",8),ue("M",B),ue("MM",B,z),ue("MMM",function(e,t){return t.monthsShortRegex(e)}),ue("MMMM",function(e,t){return t.monthsRegex(e)}),ce(["M","MM"],function(e,t){t[_e]=k(e)-1}),ce(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[_e]=i:g(n).invalidMonth=e});var We=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,He="January_February_March_April_May_June_July_August_September_October_November_December".split("_");var Re="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function Ce(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=k(t);else if(!d(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),Pe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Fe(e){return null!=e?(Ce(this,e),c.updateOffset(this,!0),this):xe(this,"Month")}var Le=ae;var Ue=ae;function Ne(){function e(e,t){return t.length-e.length}var t,n,s=[],i=[],r=[];for(t=0;t<12;t++)n=y([2e3,t]),s.push(this.monthsShort(n,"")),i.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(s.sort(e),i.sort(e),r.sort(e),t=0;t<12;t++)s[t]=de(s[t]),i[t]=de(i[t]);for(t=0;t<24;t++)r[t]=de(r[t]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+s.join("|")+")","i")}function Ge(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&0<=e&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function Ve(e,t,n){var s=7+t-n;return-((7+Ge(e,0,s).getUTCDay()-t)%7)+s-1}function Ee(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+Ve(e,s,i);return o<=0?a=De(r=e-1)+o:o>De(e)?(r=e+1,a=o-De(e)):(r=e,a=o),{year:r,dayOfYear:a}}function Ie(e,t,n){var s,i,r=Ve(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ae(i=e.year()-1,t,n):a>Ae(e.year(),t,n)?(s=a-Ae(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ae(e,t,n){var s=Ve(e,t,n),i=Ve(e+1,t,n);return(De(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),H("week","w"),H("isoWeek","W"),L("week",5),L("isoWeek",5),ue("w",B),ue("ww",B,z),ue("W",B),ue("WW",B,z),fe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=k(e)});I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),H("day","d"),H("weekday","e"),H("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),ue("d",B),ue("e",B),ue("E",B),ue("dd",function(e,t){return t.weekdaysMinRegex(e)}),ue("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ue("dddd",function(e,t){return t.weekdaysRegex(e)}),fe(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:g(n).invalidWeekday=e}),fe(["d","e","E"],function(e,t,n,s){t[s]=k(e)});var je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var ze="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var $e=ae;var qe=ae;var Je=ae;function Be(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=y([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=de(o[t]),u[t]=de(u[t]),l[t]=de(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,t){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Ke(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,Qe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)}),I("hmmss",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)+U(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+U(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+U(this.minutes(),2)+U(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),H("hour","h"),L("hour",13),ue("a",Ke),ue("A",Ke),ue("H",B),ue("h",B),ue("k",B),ue("HH",B,z),ue("hh",B,z),ue("kk",B,z),ue("hmm",Q),ue("hmmss",X),ue("Hmm",Q),ue("Hmmss",X),ce(["H","HH"],ge),ce(["k","kk"],function(e,t,n){var s=k(e);t[ge]=24===s?0:s}),ce(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ce(["h","hh"],function(e,t,n){t[ge]=k(e),g(n).bigHour=!0}),ce("hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s)),g(n).bigHour=!0}),ce("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i)),g(n).bigHour=!0}),ce("Hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s))}),ce("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:He,monthsShort:Re,week:{dow:0,doy:6},weekdays:je,weekdaysMin:ze,weekdaysShort:Ze,meridiemParse:/[ap]\.?m?\.?/i},st={},it={};function rt(e){return e?e.toLowerCase().replace("_","-"):e}function at(e){var t=null;if(!st[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),ot(t)}catch(e){}return st[e]}function ot(e,t){var n;return e&&((n=l(t)?lt(e):ut(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function ut(e,t){if(null!==t){var n,s=nt;if(t.abbr=e,null!=st[e])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=st[e]._config;else if(null!=t.parentLocale)if(null!=st[t.parentLocale])s=st[t.parentLocale]._config;else{if(null==(n=at(t.parentLocale)))return it[t.parentLocale]||(it[t.parentLocale]=[]),it[t.parentLocale].push({name:e,config:t}),null;s=n._config}return st[e]=new P(b(s,t)),it[e]&&it[e].forEach(function(e){ut(e.name,e.config)}),ot(e),st[e]}return delete st[e],null}function lt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!o(e)){if(t=at(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=rt(e[r]).split("-")).length,n=(n=rt(e[r+1]))?n.split("-"):null;0<t;){if(s=at(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&a(i,n,!0)>=t-1)break;t--}r++}return et}(e)}function dt(e){var t,n=e._a;return n&&-2===g(e).overflow&&(t=n[_e]<0||11<n[_e]?_e:n[ye]<1||n[ye]>Pe(n[me],n[_e])?ye:n[ge]<0||24<n[ge]||24===n[ge]&&(0!==n[pe]||0!==n[ve]||0!==n[we])?ge:n[pe]<0||59<n[pe]?pe:n[ve]<0||59<n[ve]?ve:n[we]<0||999<n[we]?we:-1,g(e)._overflowDayOfYear&&(t<me||ye<t)&&(t=ye),g(e)._overflowWeeks&&-1===t&&(t=Me),g(e)._overflowWeekday&&-1===t&&(t=Se),g(e).overflow=t),e}function ht(e,t,n){return null!=e?e:null!=t?t:n}function ct(e){var t,n,s,i,r,a=[];if(!e._d){var o,u;for(o=e,u=new Date(c.now()),s=o._useUTC?[u.getUTCFullYear(),u.getUTCMonth(),u.getUTCDate()]:[u.getFullYear(),u.getMonth(),u.getDate()],e._w&&null==e._a[ye]&&null==e._a[_e]&&function(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ht(t.GG,e._a[me],Ie(Tt(),1,4).year),s=ht(t.W,1),((i=ht(t.E,1))<1||7<i)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ie(Tt(),r,a);n=ht(t.gg,e._a[me],l.year),s=ht(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r}s<1||s>Ae(n,r,a)?g(e)._overflowWeeks=!0:null!=u?g(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[me]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=ht(e._a[me],s[me]),(e._dayOfYear>De(r)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),n=Ge(r,0,e._dayOfYear),e._a[_e]=n.getUTCMonth(),e._a[ye]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=s[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[pe]&&0===e._a[ve]&&0===e._a[we]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Ge:function(e,t,n,s,i,r,a){var o=new Date(e,t,n,s,i,r,a);return e<100&&0<=e&&isFinite(o.getFullYear())&&o.setFullYear(e),o}).apply(null,a),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(g(e).weekdayMismatch=!0)}}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_t=/Z|[+-]\d\d(?::?\d\d)?/,yt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],gt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],pt=/^\/?Date\((\-?\d+)/i;function vt(e){var t,n,s,i,r,a,o=e._i,u=ft.exec(o)||mt.exec(o);if(u){for(g(e).iso=!0,t=0,n=yt.length;t<n;t++)if(yt[t][1].exec(u[1])){i=yt[t][0],s=!1!==yt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[3])){r=(u[2]||" ")+gt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!_t.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),kt(e)}else e._isValid=!1}var wt=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function Mt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),Re.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}var St={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Dt(e){var t,n,s,i=wt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim());if(i){var r=Mt(i[4],i[3],i[2],i[5],i[6],i[7]);if(t=i[1],n=r,s=e,t&&Ze.indexOf(t)!==new Date(n[0],n[1],n[2]).getDay()&&(g(s).weekdayMismatch=!0,!(s._isValid=!1)))return;e._a=r,e._tzm=function(e,t,n){if(e)return St[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return(s-i)/100*60+i}(i[8],i[9],i[10]),e._d=Ge.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),g(e).rfc2822=!0}else e._isValid=!1}function kt(e){if(e._f!==c.ISO_8601)if(e._f!==c.RFC_2822){e._a=[],g(e).empty=!0;var t,n,s,i,r,a,o,u,l=""+e._i,d=l.length,h=0;for(s=j(e._f,e._locale).match(N)||[],t=0;t<s.length;t++)i=s[t],(n=(l.match(le(i,e))||[])[0])&&(0<(r=l.substr(0,l.indexOf(n))).length&&g(e).unusedInput.push(r),l=l.slice(l.indexOf(n)+n.length),h+=n.length),E[i]?(n?g(e).empty=!1:g(e).unusedTokens.push(i),a=i,u=e,null!=(o=n)&&m(he,a)&&he[a](o,u._a,u,a)):e._strict&&!n&&g(e).unusedTokens.push(i);g(e).charsLeftOver=d-h,0<l.length&&g(e).unusedInput.push(l),e._a[ge]<=12&&!0===g(e).bigHour&&0<e._a[ge]&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[ge]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[ge],e._meridiem),ct(e),dt(e)}else Dt(e);else vt(e)}function Yt(e){var t,n,s,i,r=e._i,a=e._f;return e._locale=e._locale||lt(e._l),null===r||void 0===a&&""===r?v({nullInput:!0}):("string"==typeof r&&(e._i=r=e._locale.preparse(r)),S(r)?new M(dt(r)):(h(r)?e._d=r:o(a)?function(e){var t,n,s,i,r;if(0===e._f.length)return g(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,t=w({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],kt(t),p(t)&&(r+=g(t).charsLeftOver,r+=10*g(t).unusedTokens.length,g(t).score=r,(null==s||r<s)&&(s=r,n=t));_(e,n||t)}(e):a?kt(e):l(n=(t=e)._i)?t._d=new Date(c.now()):h(n)?t._d=new Date(n.valueOf()):"string"==typeof n?(s=t,null===(i=pt.exec(s._i))?(vt(s),!1===s._isValid&&(delete s._isValid,Dt(s),!1===s._isValid&&(delete s._isValid,c.createFromInputFallback(s)))):s._d=new Date(+i[1])):o(n)?(t._a=f(n.slice(0),function(e){return parseInt(e,10)}),ct(t)):u(n)?function(e){if(!e._d){var t=C(e._i);e._a=f([t.year,t.month,t.day||t.date,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),ct(e)}}(t):d(n)?t._d=new Date(n):c.createFromInputFallback(t),p(e)||(e._d=null),e))}function Ot(e,t,n,s,i){var r,a={};return!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&function(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(e.hasOwnProperty(t))return!1;return!0}(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new M(dt(Yt(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function Tt(e,t,n,s){return Ot(e,t,n,s,!1)}c.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),c.ISO_8601=function(){},c.RFC_2822=function(){};var xt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:v()}),bt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:v()});function Pt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return Tt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Wt=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ht(e){var t=C(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,d=t.millisecond||0;this._isValid=function(e){for(var t in e)if(-1===Ye.call(Wt,t)||null!=e[t]&&isNaN(e[t]))return!1;for(var n=!1,s=0;s<Wt.length;++s)if(e[Wt[s]]){if(n)return!1;parseFloat(e[Wt[s]])!==k(e[Wt[s]])&&(n=!0)}return!0}(t),this._milliseconds=+d+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=lt(),this._bubble()}function Rt(e){return e instanceof Ht}function Ct(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){I(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+U(~~(e/60),2)+n+U(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ue("Z",re),ue("ZZ",re),ce(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Ut(re,e)});var Lt=/([\+\-]|\d\d)/gi;function Ut(e,t){var n=(t||"").match(e);if(null===n)return null;var s=((n[n.length-1]||[])+"").match(Lt)||["-",0,0],i=60*s[1]+k(s[2]);return 0===i?0:"+"===s[0]?i:-i}function Nt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(S(e)||h(e)?e.valueOf():Tt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),c.updateOffset(n,!1),n):Tt(e).local()}function Gt(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Vt(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}c.updateOffset=function(){};var Et=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,It=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function At(e,t){var n,s,i,r=e,a=null;return Rt(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:d(e)?(r={},t?r[t]=e:r.milliseconds=e):(a=Et.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:k(a[ye])*n,h:k(a[ge])*n,m:k(a[pe])*n,s:k(a[ve])*n,ms:k(Ct(1e3*a[we]))*n}):(a=It.exec(e))?(n="-"===a[1]?-1:(a[1],1),r={y:jt(a[2],n),M:jt(a[3],n),w:jt(a[4],n),d:jt(a[5],n),h:jt(a[6],n),m:jt(a[7],n),s:jt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Nt(t,e),e.isBefore(t)?n=Zt(e,t):((n=Zt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(Tt(r.from),Tt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ht(r),Rt(e)&&m(e,"_locale")&&(s._locale=e._locale),s}function jt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function Zt(e,t){var n={milliseconds:0,months:0};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function zt(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(T(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),$t(this,At(e="string"==typeof e?+e:e,t),s),this}}function $t(e,t,n,s){var i=t._milliseconds,r=Ct(t._days),a=Ct(t._months);e.isValid()&&(s=null==s||s,a&&Ce(e,xe(e,"Month")+a*n),r&&be(e,"Date",xe(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&c.updateOffset(e,r||a))}At.fn=Ht.prototype,At.invalid=function(){return At(NaN)};var qt=zt(1,"add"),Jt=zt(-1,"subtract");function Bt(e,t){var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months");return-(n+(t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(n+1,"months")-s)))||0}function Qt(e){var t;return void 0===e?this._locale._abbr:(null!=(t=lt(e))&&(this._locale=t),this)}c.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",c.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xt=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function Kt(){return this._locale}function en(e,t){I(0,[e,e.length],0,t)}function tn(e,t,n,s,i){var r;return null==e?Ie(this,s,i).year:((r=Ae(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ge(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),en("gggg","weekYear"),en("ggggg","weekYear"),en("GGGG","isoWeekYear"),en("GGGGG","isoWeekYear"),H("weekYear","gg"),H("isoWeekYear","GG"),L("weekYear",1),L("isoWeekYear",1),ue("G",se),ue("g",se),ue("GG",B,z),ue("gg",B,z),ue("GGGG",ee,q),ue("gggg",ee,q),ue("GGGGG",te,J),ue("ggggg",te,J),fe(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=k(e)}),fe(["gg","GG"],function(e,t,n,s){t[s]=c.parseTwoDigitYear(e)}),I("Q",0,"Qo","quarter"),H("quarter","Q"),L("quarter",7),ue("Q",Z),ce("Q",function(e,t){t[_e]=3*(k(e)-1)}),I("D",["DD",2],"Do","date"),H("date","D"),L("date",9),ue("D",B),ue("DD",B,z),ue("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ce(["D","DD"],ye),ce("Do",function(e,t){t[ye]=k(e.match(B)[0])});var nn=Te("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),H("dayOfYear","DDD"),L("dayOfYear",4),ue("DDD",K),ue("DDDD",$),ce(["DDD","DDDD"],function(e,t,n){n._dayOfYear=k(e)}),I("m",["mm",2],0,"minute"),H("minute","m"),L("minute",14),ue("m",B),ue("mm",B,z),ce(["m","mm"],pe);var sn=Te("Minutes",!1);I("s",["ss",2],0,"second"),H("second","s"),L("second",15),ue("s",B),ue("ss",B,z),ce(["s","ss"],ve);var rn,an=Te("Seconds",!1);for(I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),H("millisecond","ms"),L("millisecond",16),ue("S",K,Z),ue("SS",K,z),ue("SSS",K,$),rn="SSSS";rn.length<=9;rn+="S")ue(rn,ne);function on(e,t){t[we]=k(1e3*("0."+e))}for(rn="S";rn.length<=9;rn+="S")ce(rn,on);var un=Te("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var ln=M.prototype;function dn(e){return e}ln.add=qt,ln.calendar=function(e,t){var n=e||Tt(),s=Nt(n,this).startOf("day"),i=c.calendarFormat(this,s)||"sameElse",r=t&&(x(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,Tt(n)))},ln.clone=function(){return new M(this)},ln.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Nt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=R(t)){case"year":r=Bt(this,s)/12;break;case"month":r=Bt(this,s);break;case"quarter":r=Bt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:D(r)},ln.endOf=function(e){return void 0===(e=R(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},ln.format=function(e){e||(e=this.isUtc()?c.defaultFormatUtc:c.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},ln.from=function(e,t){return this.isValid()&&(S(e)&&e.isValid()||Tt(e).isValid())?At({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},ln.fromNow=function(e){return this.from(Tt(),e)},ln.to=function(e,t){return this.isValid()&&(S(e)&&e.isValid()||Tt(e).isValid())?At({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},ln.toNow=function(e){return this.to(Tt(),e)},ln.get=function(e){return x(this[e=R(e)])?this[e]():this},ln.invalidAt=function(){return g(this).overflow},ln.isAfter=function(e,t){var n=S(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(l(t)?"millisecond":t))?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},ln.isBefore=function(e,t){var n=S(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(l(t)?"millisecond":t))?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},ln.isBetween=function(e,t,n,s){return("("===(s=s||"()")[0]?this.isAfter(e,n):!this.isBefore(e,n))&&(")"===s[1]?this.isBefore(t,n):!this.isAfter(t,n))},ln.isSame=function(e,t){var n,s=S(e)?e:Tt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=R(t||"millisecond"))?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},ln.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},ln.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},ln.isValid=function(){return p(this)},ln.lang=Xt,ln.locale=Qt,ln.localeData=Kt,ln.max=bt,ln.min=xt,ln.parsingFlags=function(){return _({},g(this))},ln.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t=[];for(var n in e)t.push({unit:n,priority:F[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}(e=C(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(x(this[e=R(e)]))return this[e](t);return this},ln.startOf=function(e){switch(e=R(e)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===e&&this.weekday(0),"isoWeek"===e&&this.isoWeekday(1),"quarter"===e&&this.month(3*Math.floor(this.month()/3)),this},ln.subtract=Jt,ln.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},ln.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},ln.toDate=function(){return new Date(this.valueOf())},ln.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):x(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},ln.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i=t+'[")]';return this.format(n+s+"-MM-DD[T]HH:mm:ss.SSS"+i)},ln.toJSON=function(){return this.isValid()?this.toISOString():null},ln.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},ln.unix=function(){return Math.floor(this.valueOf()/1e3)},ln.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},ln.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},ln.year=Oe,ln.isLeapYear=function(){return ke(this.year())},ln.weekYear=function(e){return tn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},ln.isoWeekYear=function(e){return tn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},ln.quarter=ln.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},ln.month=Fe,ln.daysInMonth=function(){return Pe(this.year(),this.month())},ln.week=ln.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},ln.isoWeek=ln.isoWeeks=function(e){var t=Ie(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},ln.weeksInYear=function(){var e=this.localeData()._week;return Ae(this.year(),e.dow,e.doy)},ln.isoWeeksInYear=function(){return Ae(this.year(),1,4)},ln.date=nn,ln.day=ln.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},ln.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},ln.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=(n=e,s=this.localeData(),"string"==typeof n?s.weekdaysParse(n)%7||7:isNaN(n)?null:n);return this.day(this.day()%7?t:t-7)}return this.day()||7;var n,s},ln.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},ln.hour=ln.hours=tt,ln.minute=ln.minutes=sn,ln.second=ln.seconds=an,ln.millisecond=ln.milliseconds=un,ln.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Ut(re,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Gt(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?$t(this,At(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,c.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?i:Gt(this)},ln.utc=function(e){return this.utcOffset(0,e)},ln.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Gt(this),"m")),this},ln.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Ut(ie,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},ln.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Tt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},ln.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},ln.isLocal=function(){return!!this.isValid()&&!this._isUTC},ln.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},ln.isUtc=Vt,ln.isUTC=Vt,ln.zoneAbbr=function(){return this._isUTC?"UTC":""},ln.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},ln.dates=n("dates accessor is deprecated. Use date instead.",nn),ln.months=n("months accessor is deprecated. Use month instead",Fe),ln.years=n("years accessor is deprecated. Use year instead",Oe),ln.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),ln.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var e={};if(w(e,this),(e=Yt(e))._a){var t=e._isUTC?y(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0<a(e._a,t.toArray())}else this._isDSTShifted=!1;return this._isDSTShifted});var hn=P.prototype;function cn(e,t,n,s){var i=lt(),r=y().set(s,t);return i[n](r,e)}function fn(e,t,n){if(d(e)&&(t=e,e=void 0),e=e||"",null!=t)return cn(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=cn(e,s,n,"month");return i}function mn(e,t,n,s){"boolean"==typeof e?d(t)&&(n=t,t=void 0):(t=e,e=!1,d(n=t)&&(n=t,t=void 0)),t=t||"";var i,r=lt(),a=e?r._week.dow:0;if(null!=n)return cn(t,(n+a)%7,s,"day");var o=[];for(i=0;i<7;i++)o[i]=cn(t,(i+a)%7,s,"day");return o}hn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return x(s)?s.call(t,n):s},hn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},hn.invalidDate=function(){return this._invalidDate},hn.ordinal=function(e){return this._ordinal.replace("%d",e)},hn.preparse=dn,hn.postformat=dn,hn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return x(i)?i(e,t,n,s):i.replace(/%d/i,e)},hn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return x(n)?n(t):n.replace(/%s/i,t)},hn.set=function(e){var t,n;for(n in e)x(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},hn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||We).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},hn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[We.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},hn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=y([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=y([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},hn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=Ue),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},hn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Le),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},hn.week=function(e){return Ie(e,this._week.dow,this._week.doy).week},hn.firstDayOfYear=function(){return this._week.doy},hn.firstDayOfWeek=function(){return this._week.dow},hn.weekdays=function(e,t){return e?o(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][e.day()]:o(this._weekdays)?this._weekdays:this._weekdays.standalone},hn.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},hn.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},hn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=y([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=y([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".",".?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},hn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=$e),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},hn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=qe),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},hn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Je),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},hn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},hn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},ot("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===k(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),c.lang=n("moment.lang is deprecated. Use moment.locale instead.",ot),c.langData=n("moment.langData is deprecated. Use moment.localeData instead.",lt);var _n=Math.abs;function yn(e,t,n,s){var i=At(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function gn(e){return e<0?Math.floor(e):Math.ceil(e)}function pn(e){return 4800*e/146097}function vn(e){return 146097*e/4800}function wn(e){return function(){return this.as(e)}}var Mn=wn("ms"),Sn=wn("s"),Dn=wn("m"),kn=wn("h"),Yn=wn("d"),On=wn("w"),Tn=wn("M"),xn=wn("y");function bn(e){return function(){return this.isValid()?this._data[e]:NaN}}var Pn=bn("milliseconds"),Wn=bn("seconds"),Hn=bn("minutes"),Rn=bn("hours"),Cn=bn("days"),Fn=bn("months"),Ln=bn("years");var Un=Math.round,Nn={ss:44,s:45,m:45,h:22,d:26,M:11};var Gn=Math.abs;function Vn(e){return(0<e)-(e<0)||+e}function En(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=Gn(this._milliseconds)/1e3,s=Gn(this._days),i=Gn(this._months);t=D((e=D(n/60))/60),n%=60,e%=60;var r=D(i/12),a=i%=12,o=s,u=t,l=e,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Vn(this._months)!==Vn(h)?"-":"",m=Vn(this._days)!==Vn(h)?"-":"",_=Vn(this._milliseconds)!==Vn(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||d?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(d?_+d+"S":"")}var In=Ht.prototype;return In.isValid=function(){return this._isValid},In.abs=function(){var e=this._data;return this._milliseconds=_n(this._milliseconds),this._days=_n(this._days),this._months=_n(this._months),e.milliseconds=_n(e.milliseconds),e.seconds=_n(e.seconds),e.minutes=_n(e.minutes),e.hours=_n(e.hours),e.months=_n(e.months),e.years=_n(e.years),this},In.add=function(e,t){return yn(this,e,t,1)},In.subtract=function(e,t){return yn(this,e,t,-1)},In.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=R(e))||"year"===e)return t=this._days+s/864e5,n=this._months+pn(t),"month"===e?n:n/12;switch(t=this._days+Math.round(vn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},In.asMilliseconds=Mn,In.asSeconds=Sn,In.asMinutes=Dn,In.asHours=kn,In.asDays=Yn,In.asWeeks=On,In.asMonths=Tn,In.asYears=xn,In.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12):NaN},In._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*gn(vn(o)+a),o=a=0),u.milliseconds=r%1e3,e=D(r/1e3),u.seconds=e%60,t=D(e/60),u.minutes=t%60,n=D(t/60),u.hours=n%24,o+=i=D(pn(a+=D(n/24))),a-=gn(vn(i)),s=D(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},In.clone=function(){return At(this)},In.get=function(e){return e=R(e),this.isValid()?this[e+"s"]():NaN},In.milliseconds=Pn,In.seconds=Wn,In.minutes=Hn,In.hours=Rn,In.days=Cn,In.weeks=function(){return D(this.days()/7)},In.months=Fn,In.years=Ln,In.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t,n,s,i,r,a,o,u,l,d,h,c=this.localeData(),f=(n=!e,s=c,i=At(t=this).abs(),r=Un(i.as("s")),a=Un(i.as("m")),o=Un(i.as("h")),u=Un(i.as("d")),l=Un(i.as("M")),d=Un(i.as("y")),(h=r<=Nn.ss&&["s",r]||r<Nn.s&&["ss",r]||a<=1&&["m"]||a<Nn.m&&["mm",a]||o<=1&&["h"]||o<Nn.h&&["hh",o]||u<=1&&["d"]||u<Nn.d&&["dd",u]||l<=1&&["M"]||l<Nn.M&&["MM",l]||d<=1&&["y"]||["yy",d])[2]=n,h[3]=0<+t,h[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,h));return e&&(f=c.pastFuture(+this,f)),c.postformat(f)},In.toISOString=En,In.toString=En,In.toJSON=En,In.locale=Qt,In.localeData=Kt,In.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",En),In.lang=Xt,I("X",0,0,"unix"),I("x",0,0,"valueOf"),ue("x",se),ue("X",/[+-]?\d+(\.\d{1,3})?/),ce("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),ce("x",function(e,t,n){n._d=new Date(k(e))}),c.version="2.22.1",e=Tt,c.fn=ln,c.min=function(){return Pt("isBefore",[].slice.call(arguments,0))},c.max=function(){return Pt("isAfter",[].slice.call(arguments,0))},c.now=function(){return Date.now?Date.now():+new Date},c.utc=y,c.unix=function(e){return Tt(1e3*e)},c.months=function(e,t){return fn(e,t,"months")},c.isDate=h,c.locale=ot,c.invalid=v,c.duration=At,c.isMoment=S,c.weekdays=function(e,t,n){return mn(e,t,n,"weekdays")},c.parseZone=function(){return Tt.apply(null,arguments).parseZone()},c.localeData=lt,c.isDuration=Rt,c.monthsShort=function(e,t){return fn(e,t,"monthsShort")},c.weekdaysMin=function(e,t,n){return mn(e,t,n,"weekdaysMin")},c.defineLocale=ut,c.updateLocale=function(e,t){if(null!=t){var n,s,i=nt;null!=(s=at(e))&&(i=s._config),(n=new P(t=b(i,t))).parentLocale=st[e],st[e]=n,ot(e)}else null!=st[e]&&(null!=st[e].parentLocale?st[e]=st[e].parentLocale:null!=st[e]&&delete st[e]);return st[e]},c.locales=function(){return s(st)},c.weekdaysShort=function(e,t,n){return mn(e,t,n,"weekdaysShort")},c.normalizeUnits=R,c.relativeTimeRounding=function(e){return void 0===e?Un:"function"==typeof e&&(Un=e,!0)},c.relativeTimeThreshold=function(e,t){return void 0!==Nn[e]&&(void 0===t?Nn[e]:(Nn[e]=t,"s"===e&&(Nn.ss=t-1),!0))},c.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},c.prototype=ln,c.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"YYYY-[W]WW",MONTH:"YYYY-MM"},c});
\ No newline at end of file
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function c(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function l(e){return void 0===e}function h(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function f(e,t){var n,s=[];for(n=0;n<e.length;++n)s.push(t(e[n],n));return s}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function _(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function y(e,t,n,s){return Tt(e,t,n,s,!0).utc()}function g(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function v(e){if(null==e._isValid){var t=g(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function p(e){var t=y(NaN);return null!=e?_(g(t),e):g(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var r=c.momentProperties=[];function w(e,t){var n,s,i;if(l(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),l(t._i)||(e._i=t._i),l(t._f)||(e._f=t._f),l(t._l)||(e._l=t._l),l(t._strict)||(e._strict=t._strict),l(t._tzm)||(e._tzm=t._tzm),l(t._isUTC)||(e._isUTC=t._isUTC),l(t._offset)||(e._offset=t._offset),l(t._pf)||(e._pf=g(t)),l(t._locale)||(e._locale=t._locale),0<r.length)for(n=0;n<r.length;n++)l(i=t[s=r[n]])||(e[s]=i);return e}var t=!1;function M(e){w(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,c.updateOffset(this),t=!1)}function k(e){return e instanceof M||null!=e&&null!=e._isAMomentObject}function S(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function D(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=S(t)),n}function a(e,t,n){var s,i=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),a=0;for(s=0;s<i;s++)(n&&e[s]!==t[s]||!n&&D(e[s])!==D(t[s]))&&a++;return a+r}function Y(e){!1===c.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return _(function(){if(null!=c.deprecationHandler&&c.deprecationHandler(null,i),a){for(var e,t=[],n=0;n<arguments.length;n++){if(e="","object"==typeof arguments[n]){for(var s in e+="\n["+n+"] ",arguments[0])e+=s+": "+arguments[0][s]+", ";e=e.slice(0,-2)}else e=arguments[n];t.push(e)}Y(i+"\nArguments: "+Array.prototype.slice.call(t).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,O={};function T(e,t){null!=c.deprecationHandler&&c.deprecationHandler(e,t),O[e]||(Y(t),O[e]=!0)}function b(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function x(e,t){var n,s=_({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},_(s[n],e[n]),_(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=_({},s[n]));return s}function P(e){null!=e&&this.set(e)}c.suppressDeprecationWarnings=!1,c.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};var W={};function C(e,t){var n=e.toLowerCase();W[n]=W[n+"s"]=W[t]=e}function H(e){return"string"==typeof e?W[e]||W[e.toLowerCase()]:void 0}function R(e){var t,n,s={};for(n in e)m(e,n)&&(t=H(n))&&(s[t]=e[n]);return s}var U={};function F(e,t){U[e]=t}function L(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,G=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},E={};function I(e,t,n,s){var i=s;"string"==typeof s&&(i=function(){return this[s]()}),e&&(E[e]=i),t&&(E[t[0]]=function(){return L(i.apply(this,arguments),t[1],t[2])}),n&&(E[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=j(t,e.localeData()),V[t]=V[t]||function(s){var e,i,t,r=s.match(N);for(e=0,i=r.length;e<i;e++)E[r[e]]?r[e]=E[r[e]]:r[e]=(t=r[e]).match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"");return function(e){var t,n="";for(t=0;t<i;t++)n+=b(r[t])?r[t].call(e,s):r[t];return n}}(t),V[t](e)):e.localeData().invalidDate()}function j(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(G.lastIndex=0;0<=n&&G.test(e);)e=e.replace(G,s),G.lastIndex=0,n-=1;return e}var Z=/\d/,z=/\d\d/,$=/\d{3}/,q=/\d{4}/,J=/[+-]?\d{6}/,B=/\d\d?/,Q=/\d\d\d\d?/,X=/\d\d\d\d\d\d?/,K=/\d{1,3}/,ee=/\d{1,4}/,te=/[+-]?\d{1,6}/,ne=/\d+/,se=/[+-]?\d+/,ie=/Z|[+-]\d\d:?\d\d/gi,re=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,oe={};function ue(e,n,s){oe[e]=b(n)?n:function(e,t){return e&&s?s:n}}function le(e,t){return m(oe,e)?oe[e](t._strict,t._locale):new RegExp(he(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function he(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var de={};function ce(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),h(n)&&(s=function(e,t){t[n]=D(e)}),t=0;t<e.length;t++)de[e[t]]=s}function fe(e,i){ce(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var me=0,_e=1,ye=2,ge=3,ve=4,pe=5,we=6,Me=7,ke=8;function Se(e){return De(e)?366:365}function De(e){return e%4==0&&e%100!=0||e%400==0}I("Y",0,0,function(){var e=this.year();return e<=9999?""+e:"+"+e}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),C("year","y"),F("year",1),ue("Y",se),ue("YY",B,z),ue("YYYY",ee,q),ue("YYYYY",te,J),ue("YYYYYY",te,J),ce(["YYYYY","YYYYYY"],me),ce("YYYY",function(e,t){t[me]=2===e.length?c.parseTwoDigitYear(e):D(e)}),ce("YY",function(e,t){t[me]=c.parseTwoDigitYear(e)}),ce("Y",function(e,t){t[me]=parseInt(e,10)}),c.parseTwoDigitYear=function(e){return D(e)+(68<D(e)?1900:2e3)};var Ye,Oe=Te("FullYear",!0);function Te(t,n){return function(e){return null!=e?(xe(this,t,e),c.updateOffset(this,n),this):be(this,t)}}function be(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function xe(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&De(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Pe(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function Pe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1===s?De(e)?29:28:31-s%7%2}Ye=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t<this.length;++t)if(this[t]===e)return t;return-1},I("M",["MM",2],"Mo",function(){return this.month()+1}),I("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),I("MMMM",0,0,function(e){return this.localeData().months(this,e)}),C("month","M"),F("month",8),ue("M",B),ue("MM",B,z),ue("MMM",function(e,t){return t.monthsShortRegex(e)}),ue("MMMM",function(e,t){return t.monthsRegex(e)}),ce(["M","MM"],function(e,t){t[_e]=D(e)-1}),ce(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[_e]=i:g(n).invalidMonth=e});var We=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Ce="January_February_March_April_May_June_July_August_September_October_November_December".split("_");var He="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function Re(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=D(t);else if(!h(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),Pe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Ue(e){return null!=e?(Re(this,e),c.updateOffset(this,!0),this):be(this,"Month")}var Fe=ae;var Le=ae;function Ne(){function e(e,t){return t.length-e.length}var t,n,s=[],i=[],r=[];for(t=0;t<12;t++)n=y([2e3,t]),s.push(this.monthsShort(n,"")),i.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(s.sort(e),i.sort(e),r.sort(e),t=0;t<12;t++)s[t]=he(s[t]),i[t]=he(i[t]);for(t=0;t<24;t++)r[t]=he(r[t]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+s.join("|")+")","i")}function Ge(e){var t;if(e<100&&0<=e){var n=Array.prototype.slice.call(arguments);n[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)}else t=new Date(Date.UTC.apply(null,arguments));return t}function Ve(e,t,n){var s=7+t-n;return-((7+Ge(e,0,s).getUTCDay()-t)%7)+s-1}function Ee(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+Ve(e,s,i);return a=o<=0?Se(r=e-1)+o:o>Se(e)?(r=e+1,o-Se(e)):(r=e,o),{year:r,dayOfYear:a}}function Ie(e,t,n){var s,i,r=Ve(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ae(i=e.year()-1,t,n):a>Ae(e.year(),t,n)?(s=a-Ae(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ae(e,t,n){var s=Ve(e,t,n),i=Ve(e+1,t,n);return(Se(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),C("week","w"),C("isoWeek","W"),F("week",5),F("isoWeek",5),ue("w",B),ue("ww",B,z),ue("W",B),ue("WW",B,z),fe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=D(e)});function je(e,t){return e.slice(t,7).concat(e.slice(0,t))}I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),C("day","d"),C("weekday","e"),C("isoWeekday","E"),F("day",11),F("weekday",11),F("isoWeekday",11),ue("d",B),ue("e",B),ue("E",B),ue("dd",function(e,t){return t.weekdaysMinRegex(e)}),ue("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ue("dddd",function(e,t){return t.weekdaysRegex(e)}),fe(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:g(n).invalidWeekday=e}),fe(["d","e","E"],function(e,t,n,s){t[s]=D(e)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var $e="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var qe=ae;var Je=ae;var Be=ae;function Qe(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=y([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=he(o[t]),u[t]=he(u[t]),l[t]=he(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Xe(){return this.hours()%12||12}function Ke(e,t){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function et(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,Xe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+Xe.apply(this)+L(this.minutes(),2)}),I("hmmss",0,0,function(){return""+Xe.apply(this)+L(this.minutes(),2)+L(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+L(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+L(this.minutes(),2)+L(this.seconds(),2)}),Ke("a",!0),Ke("A",!1),C("hour","h"),F("hour",13),ue("a",et),ue("A",et),ue("H",B),ue("h",B),ue("k",B),ue("HH",B,z),ue("hh",B,z),ue("kk",B,z),ue("hmm",Q),ue("hmmss",X),ue("Hmm",Q),ue("Hmmss",X),ce(["H","HH"],ge),ce(["k","kk"],function(e,t,n){var s=D(e);t[ge]=24===s?0:s}),ce(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ce(["h","hh"],function(e,t,n){t[ge]=D(e),g(n).bigHour=!0}),ce("hmm",function(e,t,n){var s=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s)),g(n).bigHour=!0}),ce("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s,2)),t[pe]=D(e.substr(i)),g(n).bigHour=!0}),ce("Hmm",function(e,t,n){var s=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s))}),ce("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s,2)),t[pe]=D(e.substr(i))});var tt,nt=Te("Hours",!0),st={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ce,monthsShort:He,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:$e,weekdaysShort:ze,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=tt._abbr,require("./locale/"+e),ut(t)}catch(e){}return it[e]}function ut(e,t){var n;return e&&((n=l(t)?ht(e):lt(e,t))?tt=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),tt._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,s=st;if(t.abbr=e,null!=it[e])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])s=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return it[e]=new P(x(s,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),ut(e),it[e]}function ht(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return tt;if(!o(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=at(e[r]).split("-")).length,n=(n=at(e[r+1]))?n.split("-"):null;0<t;){if(s=ot(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&a(i,n,!0)>=t-1)break;t--}r++}return tt}(e)}function dt(e){var t,n=e._a;return n&&-2===g(e).overflow&&(t=n[_e]<0||11<n[_e]?_e:n[ye]<1||n[ye]>Pe(n[me],n[_e])?ye:n[ge]<0||24<n[ge]||24===n[ge]&&(0!==n[ve]||0!==n[pe]||0!==n[we])?ge:n[ve]<0||59<n[ve]?ve:n[pe]<0||59<n[pe]?pe:n[we]<0||999<n[we]?we:-1,g(e)._overflowDayOfYear&&(t<me||ye<t)&&(t=ye),g(e)._overflowWeeks&&-1===t&&(t=Me),g(e)._overflowWeekday&&-1===t&&(t=ke),g(e).overflow=t),e}function ct(e,t,n){return null!=e?e:null!=t?t:n}function ft(e){var t,n,s,i,r,a=[];if(!e._d){var o,u;for(o=e,u=new Date(c.now()),s=o._useUTC?[u.getUTCFullYear(),u.getUTCMonth(),u.getUTCDate()]:[u.getFullYear(),u.getMonth(),u.getDate()],e._w&&null==e._a[ye]&&null==e._a[_e]&&function(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ct(t.GG,e._a[me],Ie(bt(),1,4).year),s=ct(t.W,1),((i=ct(t.E,1))<1||7<i)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ie(bt(),r,a);n=ct(t.gg,e._a[me],l.year),s=ct(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r}s<1||s>Ae(n,r,a)?g(e)._overflowWeeks=!0:null!=u?g(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[me]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=ct(e._a[me],s[me]),(e._dayOfYear>Se(r)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),n=Ge(r,0,e._dayOfYear),e._a[_e]=n.getUTCMonth(),e._a[ye]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=s[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[pe]&&0===e._a[we]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Ge:function(e,t,n,s,i,r,a){var o;return e<100&&0<=e?(o=new Date(e+400,t,n,s,i,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,s,i,r,a),o}).apply(null,a),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(g(e).weekdayMismatch=!0)}}var mt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_t=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,yt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],pt=/^\/?Date\((\-?\d+)/i;function wt(e){var t,n,s,i,r,a,o=e._i,u=mt.exec(o)||_t.exec(o);if(u){for(g(e).iso=!0,t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[1])){i=gt[t][0],s=!1!==gt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=vt.length;t<n;t++)if(vt[t][1].exec(u[3])){r=(u[2]||" ")+vt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!yt.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),Yt(e)}else e._isValid=!1}var Mt=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;function kt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),He.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}var St={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Dt(e){var t,n,s,i=Mt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));if(i){var r=kt(i[4],i[3],i[2],i[5],i[6],i[7]);if(t=i[1],n=r,s=e,t&&ze.indexOf(t)!==new Date(n[0],n[1],n[2]).getDay()&&(g(s).weekdayMismatch=!0,!(s._isValid=!1)))return;e._a=r,e._tzm=function(e,t,n){if(e)return St[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return(s-i)/100*60+i}(i[8],i[9],i[10]),e._d=Ge.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),g(e).rfc2822=!0}else e._isValid=!1}function Yt(e){if(e._f!==c.ISO_8601)if(e._f!==c.RFC_2822){e._a=[],g(e).empty=!0;var t,n,s,i,r,a,o,u,l=""+e._i,h=l.length,d=0;for(s=j(e._f,e._locale).match(N)||[],t=0;t<s.length;t++)i=s[t],(n=(l.match(le(i,e))||[])[0])&&(0<(r=l.substr(0,l.indexOf(n))).length&&g(e).unusedInput.push(r),l=l.slice(l.indexOf(n)+n.length),d+=n.length),E[i]?(n?g(e).empty=!1:g(e).unusedTokens.push(i),a=i,u=e,null!=(o=n)&&m(de,a)&&de[a](o,u._a,u,a)):e._strict&&!n&&g(e).unusedTokens.push(i);g(e).charsLeftOver=h-d,0<l.length&&g(e).unusedInput.push(l),e._a[ge]<=12&&!0===g(e).bigHour&&0<e._a[ge]&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[ge]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[ge],e._meridiem),ft(e),dt(e)}else Dt(e);else wt(e)}function Ot(e){var t,n,s,i,r=e._i,a=e._f;return e._locale=e._locale||ht(e._l),null===r||void 0===a&&""===r?p({nullInput:!0}):("string"==typeof r&&(e._i=r=e._locale.preparse(r)),k(r)?new M(dt(r)):(d(r)?e._d=r:o(a)?function(e){var t,n,s,i,r;if(0===e._f.length)return g(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,t=w({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],Yt(t),v(t)&&(r+=g(t).charsLeftOver,r+=10*g(t).unusedTokens.length,g(t).score=r,(null==s||r<s)&&(s=r,n=t));_(e,n||t)}(e):a?Yt(e):l(n=(t=e)._i)?t._d=new Date(c.now()):d(n)?t._d=new Date(n.valueOf()):"string"==typeof n?(s=t,null===(i=pt.exec(s._i))?(wt(s),!1===s._isValid&&(delete s._isValid,Dt(s),!1===s._isValid&&(delete s._isValid,c.createFromInputFallback(s)))):s._d=new Date(+i[1])):o(n)?(t._a=f(n.slice(0),function(e){return parseInt(e,10)}),ft(t)):u(n)?function(e){if(!e._d){var t=R(e._i);e._a=f([t.year,t.month,t.day||t.date,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),ft(e)}}(t):h(n)?t._d=new Date(n):c.createFromInputFallback(t),v(e)||(e._d=null),e))}function Tt(e,t,n,s,i){var r,a={};return!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&function(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(e.hasOwnProperty(t))return!1;return!0}(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new M(dt(Ot(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function bt(e,t,n,s){return Tt(e,t,n,s,!1)}c.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),c.ISO_8601=function(){},c.RFC_2822=function(){};var xt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=bt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:p()}),Pt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=bt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:p()});function Wt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return bt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Ct=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ht(e){var t=R(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||t.isoWeek||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,h=t.millisecond||0;this._isValid=function(e){for(var t in e)if(-1===Ye.call(Ct,t)||null!=e[t]&&isNaN(e[t]))return!1;for(var n=!1,s=0;s<Ct.length;++s)if(e[Ct[s]]){if(n)return!1;parseFloat(e[Ct[s]])!==D(e[Ct[s]])&&(n=!0)}return!0}(t),this._milliseconds=+h+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=ht(),this._bubble()}function Rt(e){return e instanceof Ht}function Ut(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){I(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+L(~~(e/60),2)+n+L(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ue("Z",re),ue("ZZ",re),ce(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Nt(re,e)});var Lt=/([\+\-]|\d\d)/gi;function Nt(e,t){var n=(t||"").match(e);if(null===n)return null;var s=((n[n.length-1]||[])+"").match(Lt)||["-",0,0],i=60*s[1]+D(s[2]);return 0===i?0:"+"===s[0]?i:-i}function Gt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(k(e)||d(e)?e.valueOf():bt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),c.updateOffset(n,!1),n):bt(e).local()}function Vt(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Et(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}c.updateOffset=function(){};var It=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,At=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function jt(e,t){var n,s,i,r=e,a=null;return Rt(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:h(e)?(r={},t?r[t]=e:r.milliseconds=e):(a=It.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:D(a[ye])*n,h:D(a[ge])*n,m:D(a[ve])*n,s:D(a[pe])*n,ms:D(Ut(1e3*a[we]))*n}):(a=At.exec(e))?(n="-"===a[1]?-1:1,r={y:Zt(a[2],n),M:Zt(a[3],n),w:Zt(a[4],n),d:Zt(a[5],n),h:Zt(a[6],n),m:Zt(a[7],n),s:Zt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Gt(t,e),e.isBefore(t)?n=zt(e,t):((n=zt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(bt(r.from),bt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ht(r),Rt(e)&&m(e,"_locale")&&(s._locale=e._locale),s}function Zt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function zt(e,t){var n={};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function $t(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(T(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),qt(this,jt(e="string"==typeof e?+e:e,t),s),this}}function qt(e,t,n,s){var i=t._milliseconds,r=Ut(t._days),a=Ut(t._months);e.isValid()&&(s=null==s||s,a&&Re(e,be(e,"Month")+a*n),r&&xe(e,"Date",be(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&c.updateOffset(e,r||a))}jt.fn=Ht.prototype,jt.invalid=function(){return jt(NaN)};var Jt=$t(1,"add"),Bt=$t(-1,"subtract");function Qt(e,t){var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months");return-(n+(t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(n+1,"months")-s)))||0}function Xt(e){var t;return void 0===e?this._locale._abbr:(null!=(t=ht(e))&&(this._locale=t),this)}c.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",c.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Kt=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function en(){return this._locale}var tn=126227808e5;function nn(e,t){return(e%t+t)%t}function sn(e,t,n){return e<100&&0<=e?new Date(e+400,t,n)-tn:new Date(e,t,n).valueOf()}function rn(e,t,n){return e<100&&0<=e?Date.UTC(e+400,t,n)-tn:Date.UTC(e,t,n)}function an(e,t){I(0,[e,e.length],0,t)}function on(e,t,n,s,i){var r;return null==e?Ie(this,s,i).year:((r=Ae(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ge(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),an("gggg","weekYear"),an("ggggg","weekYear"),an("GGGG","isoWeekYear"),an("GGGGG","isoWeekYear"),C("weekYear","gg"),C("isoWeekYear","GG"),F("weekYear",1),F("isoWeekYear",1),ue("G",se),ue("g",se),ue("GG",B,z),ue("gg",B,z),ue("GGGG",ee,q),ue("gggg",ee,q),ue("GGGGG",te,J),ue("ggggg",te,J),fe(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=D(e)}),fe(["gg","GG"],function(e,t,n,s){t[s]=c.parseTwoDigitYear(e)}),I("Q",0,"Qo","quarter"),C("quarter","Q"),F("quarter",7),ue("Q",Z),ce("Q",function(e,t){t[_e]=3*(D(e)-1)}),I("D",["DD",2],"Do","date"),C("date","D"),F("date",9),ue("D",B),ue("DD",B,z),ue("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ce(["D","DD"],ye),ce("Do",function(e,t){t[ye]=D(e.match(B)[0])});var un=Te("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),C("dayOfYear","DDD"),F("dayOfYear",4),ue("DDD",K),ue("DDDD",$),ce(["DDD","DDDD"],function(e,t,n){n._dayOfYear=D(e)}),I("m",["mm",2],0,"minute"),C("minute","m"),F("minute",14),ue("m",B),ue("mm",B,z),ce(["m","mm"],ve);var ln=Te("Minutes",!1);I("s",["ss",2],0,"second"),C("second","s"),F("second",15),ue("s",B),ue("ss",B,z),ce(["s","ss"],pe);var hn,dn=Te("Seconds",!1);for(I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),C("millisecond","ms"),F("millisecond",16),ue("S",K,Z),ue("SS",K,z),ue("SSS",K,$),hn="SSSS";hn.length<=9;hn+="S")ue(hn,ne);function cn(e,t){t[we]=D(1e3*("0."+e))}for(hn="S";hn.length<=9;hn+="S")ce(hn,cn);var fn=Te("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var mn=M.prototype;function _n(e){return e}mn.add=Jt,mn.calendar=function(e,t){var n=e||bt(),s=Gt(n,this).startOf("day"),i=c.calendarFormat(this,s)||"sameElse",r=t&&(b(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,bt(n)))},mn.clone=function(){return new M(this)},mn.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Gt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=H(t)){case"year":r=Qt(this,s)/12;break;case"month":r=Qt(this,s);break;case"quarter":r=Qt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:S(r)},mn.endOf=function(e){var t;if(void 0===(e=H(e))||"millisecond"===e||!this.isValid())return this;var n=this._isUTC?rn:sn;switch(e){case"year":t=n(this.year()+1,0,1)-1;break;case"quarter":t=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":t=n(this.year(),this.month()+1,1)-1;break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":t=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":t=this._d.valueOf(),t+=36e5-nn(t+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":t=this._d.valueOf(),t+=6e4-nn(t,6e4)-1;break;case"second":t=this._d.valueOf(),t+=1e3-nn(t,1e3)-1;break}return this._d.setTime(t),c.updateOffset(this,!0),this},mn.format=function(e){e||(e=this.isUtc()?c.defaultFormatUtc:c.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},mn.from=function(e,t){return this.isValid()&&(k(e)&&e.isValid()||bt(e).isValid())?jt({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},mn.fromNow=function(e){return this.from(bt(),e)},mn.to=function(e,t){return this.isValid()&&(k(e)&&e.isValid()||bt(e).isValid())?jt({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},mn.toNow=function(e){return this.to(bt(),e)},mn.get=function(e){return b(this[e=H(e)])?this[e]():this},mn.invalidAt=function(){return g(this).overflow},mn.isAfter=function(e,t){var n=k(e)?e:bt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=H(t)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},mn.isBefore=function(e,t){var n=k(e)?e:bt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=H(t)||"millisecond")?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},mn.isBetween=function(e,t,n,s){var i=k(e)?e:bt(e),r=k(t)?t:bt(t);return!!(this.isValid()&&i.isValid()&&r.isValid())&&("("===(s=s||"()")[0]?this.isAfter(i,n):!this.isBefore(i,n))&&(")"===s[1]?this.isBefore(r,n):!this.isAfter(r,n))},mn.isSame=function(e,t){var n,s=k(e)?e:bt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=H(t)||"millisecond")?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},mn.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},mn.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},mn.isValid=function(){return v(this)},mn.lang=Kt,mn.locale=Xt,mn.localeData=en,mn.max=Pt,mn.min=xt,mn.parsingFlags=function(){return _({},g(this))},mn.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t=[];for(var n in e)t.push({unit:n,priority:U[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}(e=R(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(b(this[e=H(e)]))return this[e](t);return this},mn.startOf=function(e){var t;if(void 0===(e=H(e))||"millisecond"===e||!this.isValid())return this;var n=this._isUTC?rn:sn;switch(e){case"year":t=n(this.year(),0,1);break;case"quarter":t=n(this.year(),this.month()-this.month()%3,1);break;case"month":t=n(this.year(),this.month(),1);break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":t=n(this.year(),this.month(),this.date());break;case"hour":t=this._d.valueOf(),t-=nn(t+(this._isUTC?0:6e4*this.utcOffset()),36e5);break;case"minute":t=this._d.valueOf(),t-=nn(t,6e4);break;case"second":t=this._d.valueOf(),t-=nn(t,1e3);break}return this._d.setTime(t),c.updateOffset(this,!0),this},mn.subtract=Bt,mn.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},mn.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},mn.toDate=function(){return new Date(this.valueOf())},mn.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):b(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},mn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i=t+'[")]';return this.format(n+s+"-MM-DD[T]HH:mm:ss.SSS"+i)},mn.toJSON=function(){return this.isValid()?this.toISOString():null},mn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},mn.unix=function(){return Math.floor(this.valueOf()/1e3)},mn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},mn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},mn.year=Oe,mn.isLeapYear=function(){return De(this.year())},mn.weekYear=function(e){return on.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},mn.isoWeekYear=function(e){return on.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},mn.quarter=mn.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},mn.month=Ue,mn.daysInMonth=function(){return Pe(this.year(),this.month())},mn.week=mn.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},mn.isoWeek=mn.isoWeeks=function(e){var t=Ie(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},mn.weeksInYear=function(){var e=this.localeData()._week;return Ae(this.year(),e.dow,e.doy)},mn.isoWeeksInYear=function(){return Ae(this.year(),1,4)},mn.date=un,mn.day=mn.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},mn.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},mn.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null==e)return this.day()||7;var t,n,s=(t=e,n=this.localeData(),"string"==typeof t?n.weekdaysParse(t)%7||7:isNaN(t)?null:t);return this.day(this.day()%7?s:s-7)},mn.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},mn.hour=mn.hours=nt,mn.minute=mn.minutes=ln,mn.second=mn.seconds=dn,mn.millisecond=mn.milliseconds=fn,mn.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null==e)return this._isUTC?i:Vt(this);if("string"==typeof e){if(null===(e=Nt(re,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Vt(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?qt(this,jt(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,c.updateOffset(this,!0),this._changeInProgress=null)),this},mn.utc=function(e){return this.utcOffset(0,e)},mn.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Vt(this),"m")),this},mn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Nt(ie,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},mn.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?bt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},mn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},mn.isLocal=function(){return!!this.isValid()&&!this._isUTC},mn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},mn.isUtc=Et,mn.isUTC=Et,mn.zoneAbbr=function(){return this._isUTC?"UTC":""},mn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},mn.dates=n("dates accessor is deprecated. Use date instead.",un),mn.months=n("months accessor is deprecated. Use month instead",Ue),mn.years=n("years accessor is deprecated. Use year instead",Oe),mn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),mn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var e={};if(w(e,this),(e=Ot(e))._a){var t=e._isUTC?y(e._a):bt(e._a);this._isDSTShifted=this.isValid()&&0<a(e._a,t.toArray())}else this._isDSTShifted=!1;return this._isDSTShifted});var yn=P.prototype;function gn(e,t,n,s){var i=ht(),r=y().set(s,t);return i[n](r,e)}function vn(e,t,n){if(h(e)&&(t=e,e=void 0),e=e||"",null!=t)return gn(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=gn(e,s,n,"month");return i}function pn(e,t,n,s){t=("boolean"==typeof e?h(t)&&(n=t,t=void 0):(t=e,e=!1,h(n=t)&&(n=t,t=void 0)),t||"");var i,r=ht(),a=e?r._week.dow:0;if(null!=n)return gn(t,(n+a)%7,s,"day");var o=[];for(i=0;i<7;i++)o[i]=gn(t,(i+a)%7,s,"day");return o}yn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return b(s)?s.call(t,n):s},yn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},yn.invalidDate=function(){return this._invalidDate},yn.ordinal=function(e){return this._ordinal.replace("%d",e)},yn.preparse=_n,yn.postformat=_n,yn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return b(i)?i(e,t,n,s):i.replace(/%d/i,e)},yn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return b(n)?n(t):n.replace(/%s/i,t)},yn.set=function(e){var t,n;for(n in e)b(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},yn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||We).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},yn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[We.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},yn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=y([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=y([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},yn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=Le),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},yn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Fe),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},yn.week=function(e){return Ie(e,this._week.dow,this._week.doy).week},yn.firstDayOfYear=function(){return this._week.doy},yn.firstDayOfWeek=function(){return this._week.dow},yn.weekdays=function(e,t){var n=o(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?je(n,this._week.dow):e?n[e.day()]:n},yn.weekdaysMin=function(e){return!0===e?je(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},yn.weekdaysShort=function(e){return!0===e?je(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},yn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=y([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=y([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},yn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=qe),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},yn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Je),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},yn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Be),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},yn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},yn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},ut("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===D(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),c.lang=n("moment.lang is deprecated. Use moment.locale instead.",ut),c.langData=n("moment.langData is deprecated. Use moment.localeData instead.",ht);var wn=Math.abs;function Mn(e,t,n,s){var i=jt(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function kn(e){return e<0?Math.floor(e):Math.ceil(e)}function Sn(e){return 4800*e/146097}function Dn(e){return 146097*e/4800}function Yn(e){return function(){return this.as(e)}}var On=Yn("ms"),Tn=Yn("s"),bn=Yn("m"),xn=Yn("h"),Pn=Yn("d"),Wn=Yn("w"),Cn=Yn("M"),Hn=Yn("Q"),Rn=Yn("y");function Un(e){return function(){return this.isValid()?this._data[e]:NaN}}var Fn=Un("milliseconds"),Ln=Un("seconds"),Nn=Un("minutes"),Gn=Un("hours"),Vn=Un("days"),En=Un("months"),In=Un("years");var An=Math.round,jn={ss:44,s:45,m:45,h:22,d:26,M:11};var Zn=Math.abs;function zn(e){return(0<e)-(e<0)||+e}function $n(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=Zn(this._milliseconds)/1e3,s=Zn(this._days),i=Zn(this._months);t=S((e=S(n/60))/60),n%=60,e%=60;var r=S(i/12),a=i%=12,o=s,u=t,l=e,h=n?n.toFixed(3).replace(/\.?0+$/,""):"",d=this.asSeconds();if(!d)return"P0D";var c=d<0?"-":"",f=zn(this._months)!==zn(d)?"-":"",m=zn(this._days)!==zn(d)?"-":"",_=zn(this._milliseconds)!==zn(d)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||h?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(h?_+h+"S":"")}var qn=Ht.prototype;return qn.isValid=function(){return this._isValid},qn.abs=function(){var e=this._data;return this._milliseconds=wn(this._milliseconds),this._days=wn(this._days),this._months=wn(this._months),e.milliseconds=wn(e.milliseconds),e.seconds=wn(e.seconds),e.minutes=wn(e.minutes),e.hours=wn(e.hours),e.months=wn(e.months),e.years=wn(e.years),this},qn.add=function(e,t){return Mn(this,e,t,1)},qn.subtract=function(e,t){return Mn(this,e,t,-1)},qn.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=H(e))||"quarter"===e||"year"===e)switch(t=this._days+s/864e5,n=this._months+Sn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(Dn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},qn.asMilliseconds=On,qn.asSeconds=Tn,qn.asMinutes=bn,qn.asHours=xn,qn.asDays=Pn,qn.asWeeks=Wn,qn.asMonths=Cn,qn.asQuarters=Hn,qn.asYears=Rn,qn.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*D(this._months/12):NaN},qn._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*kn(Dn(o)+a),o=a=0),u.milliseconds=r%1e3,e=S(r/1e3),u.seconds=e%60,t=S(e/60),u.minutes=t%60,n=S(t/60),u.hours=n%24,o+=i=S(Sn(a+=S(n/24))),a-=kn(Dn(i)),s=S(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},qn.clone=function(){return jt(this)},qn.get=function(e){return e=H(e),this.isValid()?this[e+"s"]():NaN},qn.milliseconds=Fn,qn.seconds=Ln,qn.minutes=Nn,qn.hours=Gn,qn.days=Vn,qn.weeks=function(){return S(this.days()/7)},qn.months=En,qn.years=In,qn.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t,n,s,i,r,a,o,u,l,h,d,c=this.localeData(),f=(n=!e,s=c,i=jt(t=this).abs(),r=An(i.as("s")),a=An(i.as("m")),o=An(i.as("h")),u=An(i.as("d")),l=An(i.as("M")),h=An(i.as("y")),(d=r<=jn.ss&&["s",r]||r<jn.s&&["ss",r]||a<=1&&["m"]||a<jn.m&&["mm",a]||o<=1&&["h"]||o<jn.h&&["hh",o]||u<=1&&["d"]||u<jn.d&&["dd",u]||l<=1&&["M"]||l<jn.M&&["MM",l]||h<=1&&["y"]||["yy",h])[2]=n,d[3]=0<+t,d[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,d));return e&&(f=c.pastFuture(+this,f)),c.postformat(f)},qn.toISOString=$n,qn.toString=$n,qn.toJSON=$n,qn.locale=Xt,qn.localeData=en,qn.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",$n),qn.lang=Kt,I("X",0,0,"unix"),I("x",0,0,"valueOf"),ue("x",se),ue("X",/[+-]?\d+(\.\d{1,3})?/),ce("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),ce("x",function(e,t,n){n._d=new Date(D(e))}),c.version="2.24.0",e=bt,c.fn=mn,c.min=function(){return Wt("isBefore",[].slice.call(arguments,0))},c.max=function(){return Wt("isAfter",[].slice.call(arguments,0))},c.now=function(){return Date.now?Date.now():+new Date},c.utc=y,c.unix=function(e){return bt(1e3*e)},c.months=function(e,t){return vn(e,t,"months")},c.isDate=d,c.locale=ut,c.invalid=p,c.duration=jt,c.isMoment=k,c.weekdays=function(e,t,n){return pn(e,t,n,"weekdays")},c.parseZone=function(){return bt.apply(null,arguments).parseZone()},c.localeData=ht,c.isDuration=Rt,c.monthsShort=function(e,t){return vn(e,t,"monthsShort")},c.weekdaysMin=function(e,t,n){return pn(e,t,n,"weekdaysMin")},c.defineLocale=lt,c.updateLocale=function(e,t){if(null!=t){var n,s,i=st;null!=(s=ot(e))&&(i=s._config),(n=new P(t=x(i,t))).parentLocale=it[e],it[e]=n,ut(e)}else null!=it[e]&&(null!=it[e].parentLocale?it[e]=it[e].parentLocale:null!=it[e]&&delete it[e]);return it[e]},c.locales=function(){return s(it)},c.weekdaysShort=function(e,t,n){return pn(e,t,n,"weekdaysShort")},c.normalizeUnits=H,c.relativeTimeRounding=function(e){return void 0===e?An:"function"==typeof e&&(An=e,!0)},c.relativeTimeThreshold=function(e,t){return void 0!==jn[e]&&(void 0===t?jn[e]:(jn[e]=t,"s"===e&&(jn.ss=t-1),!0))},c.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},c.prototype=mn,c.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},c});
\ No newline at end of file
return true}function i(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function o(n,t){return!(null==n||!n.length)&&-1<v(n,t,0)}function f(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function c(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function a(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function l(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);
return r}function s(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function h(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function p(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function _(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function v(n,t,r){if(t===t)n:{--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=_(n,d,r);return n}function g(n,t,r,e){
--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function d(n){return n!==n}function y(n,t){var r=null==n?0:n.length;return r?m(n,t)/r:F}function b(n){return function(t){return null==t?T:t[n]}}function x(n){return function(t){return null==n?T:n[t]}}function j(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function w(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function m(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==T&&(r=r===T?i:r+i)}return r;
-}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function k(n,t){return c(t,function(t){return[t,n[t]]})}function E(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Ln[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
-}),r}function U(n,t){return function(r){return n(t(r))}}function B(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function L(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
-}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,kn="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",En=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+kn+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Un={};
-Un["[object Float32Array]"]=Un["[object Float64Array]"]=Un["[object Int8Array]"]=Un["[object Int16Array]"]=Un["[object Int32Array]"]=Un["[object Uint8Array]"]=Un["[object Uint8ClampedArray]"]=Un["[object Uint16Array]"]=Un["[object Uint32Array]"]=true,Un["[object Arguments]"]=Un["[object Array]"]=Un["[object ArrayBuffer]"]=Un["[object Boolean]"]=Un["[object DataView]"]=Un["[object Date]"]=Un["[object Error]"]=Un["[object Function]"]=Un["[object Map]"]=Un["[object Number]"]=Un["[object Object]"]=Un["[object RegExp]"]=Un["[object Set]"]=Un["[object String]"]=Un["[object WeakMap]"]=false;
-var Bn={};Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object DataView]"]=Bn["[object Boolean]"]=Bn["[object Date]"]=Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object Symbol]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,
-Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object WeakMap]"]=false;var Ln={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){
-try{var n=Nn&&Nn.require&&Nn.require("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e",
-"\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a",
-"\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I",
-"\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r",
-"\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ",
-"\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&","<":"<",">":">",'"':""","'":"'"}),tt=x({"&":"&","<":"<",">":">",""":'"',"'":"'"}),rt=function x(mn){function An(n){if(yu(n)&&!ff(n)&&!(n instanceof Ln)){if(n instanceof On)return n;if(oi.call(n,"__wrapped__"))return Fe(n)}return new On(n)}function kn(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Ln(n){
-this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Fn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Fn;++t<r;)this.add(n[t]);
-}function Zn(n){this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=ff(n),u=!e&&of(n),i=!e&&!u&&af(n),o=!e&&!u&&!i&&_f(n),u=(e=e||u||i||o)?A(n.length,ni):[],f=u.length;for(r in n)!t&&!oi.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return De(Lr(n),pt(t,0,n.length))}function ut(n){return De(Lr(n))}function it(n,t,r){(r===T||lu(n[t],r))&&(r!==T||t in n)||st(n,t,r);
-}function ot(n,t,r){var e=n[t];oi.call(n,t)&&lu(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(lu(n[r][0],t))return r;return-1}function ct(n,t,r,e){return uo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,Wu(t),n)}function lt(n,t){return n&&Cr(t,Uu(t),n)}function st(n,t,r){"__proto__"==t&&Ai?Ai(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Ku(e),i=null==n;++r<e;)u[r]=i?T:Ru(n,t[r]);return u;
-}function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!du(n))return n;if(u=ff(n)){if(f=me(n),!c)return Lr(n,f)}else{var s=vo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(af(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Bn[s])return i?n:{};f=ke(n,s,c)}}if(o||(o=new Zn),
-i=o.get(n))return i;if(o.set(n,f),pf(n))return n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}),f;if(sf(n))return n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))}),f;var a=l?a?ve:_e:a?Uu:Wu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=Wu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Qu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ti("Expected a function");
-return bo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,E(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return uo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!wu(o):r(o,f)))var f=o,c=i;
-}return c}function jt(n,t){var r=[];return uo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Ee),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&oo(n,t,Wu)}function At(n,t){return n&&fo(n,t,Wu)}function kt(n,t){return i(t,function(t){return _u(n[t])})}function Et(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Me(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
-ff(n)?t:a(t,r(n))}function Ot(n){if(null==n)return n===T?"[object Undefined]":"[object Null]";if(mi&&mi in Qu(n)){var t=oi.call(n,mi),r=n[mi];try{n[mi]=T;var e=true}catch(n){}var u=ai.call(n);e&&(t?n[mi]=r:delete n[mi]),n=u}else n=ai.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&oi.call(n,t)}function zt(n,t){return null!=n&&t in Qu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Ku(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,E(t))),s=Ci(p.length,s),
-l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Ut(n,t,r,e){return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Bt(t,r,e){return r=Sr(r,t),t=2>r.length?t:Et(t,hr(r,0,-1)),r=null==t?t:t[Me(Ve(r))],null==r?T:n(r,t,e)}function Lt(n){return yu(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
-return yu(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return yu(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)return true;if(null==n||null==t||!yu(n)&&!yu(t))return n!==n&&t!==t;n:{var i=ff(n),o=ff(t),f=i?"[object Array]":vo(n),c=o?"[object Array]":vo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&af(n)){if(!af(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||_f(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
+}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function E(n,t){return c(t,function(t){return[t,n[t]]})}function k(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Un[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
+}),r}function B(n,t){return function(r){return n(t(r))}}function L(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function U(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
+}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={};
+Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false;
+var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true,
+Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){
+try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I",
+"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C",
+"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i",
+"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r",
+"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij",
+"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&","<":"<",">":">",'"':""","'":"'"}),tt=x({"&":"&","<":"<",">":">",""":'"',"'":"'"}),rt=function x(mn){function An(n){if(yu(n)&&!ff(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(oi.call(n,"__wrapped__"))return Fe(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n,
+this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Fn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Fn;++t<r;)this.add(n[t]);
+}function Zn(n){this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=ff(n),u=!e&&of(n),i=!e&&!u&&af(n),o=!e&&!u&&!i&&_f(n),u=(e=e||u||i||o)?A(n.length,ni):[],f=u.length;for(r in n)!t&&!oi.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return De(Ur(n),pt(t,0,n.length))}function ut(n){return De(Ur(n))}function it(n,t,r){(r===T||lu(n[t],r))&&(r!==T||t in n)||st(n,t,r);
+}function ot(n,t,r){var e=n[t];oi.call(n,t)&&lu(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(lu(n[r][0],t))return r;return-1}function ct(n,t,r,e){return uo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,Wu(t),n)}function lt(n,t){return n&&Cr(t,Bu(t),n)}function st(n,t,r){"__proto__"==t&&Ai?Ai(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Ku(e),i=null==n;++r<e;)u[r]=i?T:Ru(n,t[r]);return u;
+}function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!du(n))return n;if(u=ff(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=vo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(af(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn),
+i=o.get(n))return i;o.set(n,f),pf(n)?n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}):sf(n)&&n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))});var a=l?a?ve:_e:a?Bu:Wu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=Wu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Qu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ti("Expected a function");
+return bo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return uo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!wu(o):r(o,f)))var f=o,c=i;
+}return c}function jt(n,t){var r=[];return uo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=ke),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&oo(n,t,Wu)}function At(n,t){return n&&fo(n,t,Wu)}function Et(n,t){return i(t,function(t){return _u(n[t])})}function kt(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Me(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
+ff(n)?t:a(t,r(n))}function Ot(n){if(null==n)n=n===T?"[object Undefined]":"[object Null]";else if(mi&&mi in Qu(n)){var t=oi.call(n,mi),r=n[mi];try{n[mi]=T;var e=true}catch(n){}var u=ai.call(n);e&&(t?n[mi]=r:delete n[mi]),n=u}else n=ai.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&oi.call(n,t)}function zt(n,t){return null!=n&&t in Qu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Ku(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ci(p.length,s),
+l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Bt(n,t,r){var e={};return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Lt(t,r,e){return r=Sr(r,t),t=2>r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[Me(Ve(r))],null==r?T:n(r,t,e)}function Ut(n){return yu(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
+return yu(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return yu(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!yu(n)&&!yu(t))t=n!==n&&t!==t;else n:{var i=ff(n),o=ff(t),f=i?"[object Array]":vo(n),c=o?"[object Array]":vo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&af(n)){if(!af(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||_f(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
if(!(1&r)&&(i=a&&oi.call(n,"__wrapped__"),f=o&&oi.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:oi.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===T?h!==p&&!Mt(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l);
}c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Tt(n){return yu(n)&&"[object Map]"==vo(n)}function $t(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=Qu(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===T&&!(c in n))return false;
-}else{if(f=new Zn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!du(n)||ci&&ci in n)&&(_u(n)?hi:dn).test(Te(n))}function Nt(n){return yu(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return yu(n)&&"[object Set]"==vo(n)}function Zt(n){return yu(n)&&gu(n.length)&&!!Un[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?$u:typeof n=="object"?ff(n)?Jt(n[0],n[1]):Ht(n):Zu(n)}function Vt(n){if(!ze(n))return Bi(n);var t,r=[];for(t in Qu(n))oi.call(n,t)&&"constructor"!=t&&r.push(t);
-return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=su(n)?Ku(n.length):[];return uo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!du(t)?We(Me(n),t):function(r){var e=Ru(r,n);return e===T&&e===t?zu(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&oo(t,function(i,o){if(du(i)){u||(u=new Zn);var f=u,c=Be(n,o),a=Be(t,o),l=f.get(a);if(!l){var l=e?e(c,a,o+"",n,t,f):T,s=l===T;
-if(s){var h=ff(a),p=!h&&af(a),_=!h&&!p&&_f(a),l=a;h||p||_?ff(c)?l=c:hu(c)?l=Lr(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:xu(a)||of(a)?(l=c,of(c)?l=Ou(c):du(c)&&!_u(c)||(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a))}it(n,o,l)}else f=e?e(Be(n,o),i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Uu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[$u],E(ye())),n=Gt(n,function(n,r,u){return{a:c(t,function(t){return t(n)}),
-b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){if(e>=f){e=c;break n}e=c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return zu(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=Et(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return Et(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;for(n===t&&(t=Lr(t)),r&&(f=c(n,E(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&xi.call(f,a,1),
-xi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?xi.call(n,u,1):xr(n,u)}}return n}function ir(n,t){return n+Ii(Ti()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Ii(t/2))&&(n+=n);while(t);return r}function fr(n,t){return xo(Ue(n,t,$u),n+"")}function cr(n){return Qn(Lu(n))}function ar(n,t){var r=Lu(n);return De(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!du(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){
-var c=Me(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=du(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return De(Lu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Ku(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return uo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!wu(o)&&(r?o<=t:o<t)?e=i+1:u=i;
-}return u}return vr(n,t,$u,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=wu(t),a=t===T;u<i;){var l=Ii((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=wu(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ci(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r],f=t?t(o):o;if(!r||!lu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:wu(n)?F:+n}function yr(n){
-if(typeof n=="string")return n;if(ff(n))return c(n,yr)+"";if(wu(n))return ro?ro.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:so(n))return L(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),
-n=2>t.length?n:Et(n,hr(t,0,-1)),null==n||delete n[Me(Ve(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Ln&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Ku(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));return br(wt(i,1),t,r)}function Ar(n,t,r){
-for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function kr(n){return hu(n)?n:[]}function Er(n){return typeof n=="function"?n:$u}function Sr(n,t){return ff(n)?n:Ie(n,t)?[n]:jo(Iu(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=gi?gi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new vi(t).set(new vi(n)),t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length);
-}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=wu(n),o=t!==T,f=null===t,c=t===t,a=wu(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Ur(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Li(i-o,0),l=Ku(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l}function Br(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Li(i-f,0),s=Ku(l+a);
-for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Lr(n,t){var r=-1,e=n.length;for(t||(t=Ku(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,po(n),t)}function Mr(n,t){return Cr(n,_o(n),t)}function Tr(n,r){return function(e,u){var i=ff(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o);
-}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Qu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!su(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Qu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){var u=-1,i=Qu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break;
-}return t}}function Pr(n,t,r){function e(){return(this&&this!==$n&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Iu(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Mu(Du(t).replace(En,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:
-return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=eo(n.prototype),t=n.apply(r,t);return du(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Ku(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:B(f,a),o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==$n&&this instanceof u?i:t,this,f);
-}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Qu(t);if(!su(t)){var i=ye(r,3);t=Wu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ti("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?ho(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
-return function(){var n=arguments,e=n[0];if(o&&1==n.length&&ff(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Ku(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Ur(y,e,u,_)),i&&(y=Br(y,i,o,_)),d-=x,_&&d<a)return j=B(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ci(f.length,x),m=Lr(y);w--;){
-var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==$n&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Ut(r,n,t(e),{})}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
-return r=c(r,E(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Oi(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Ku(l+c),h=this&&this!==$n&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
-e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=Au(t),r===T?(r=t,t=0):r=Au(r),e=e===T?t<r?1:-1:Au(e);var u=-1;r=Li(Oi((r-t)/(e||1)),0);for(var i=Ku(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Su(t),r=Su(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&yo(r,u),r.placeholder=e,Le(r,n,t)}function ie(n){
-var t=Yu[n];return function(n,r){if(n=Su(n),r=null==r?0:Ci(ku(r),292)){var e=(Iu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Iu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=vo(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):k(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ti("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Li(ku(o),0),f=f===T?f:ku(f),a-=u?u.length:0,64&t){
-var l=e,s=u;e=u=T}var h=c?T:ho(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Ur(e,r,h[4]):r,i[4]=e?B(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Br(e,r,h[6]):r,i[6]=e?B(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ci(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1],
-r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Li(i[9]-a,0),!f&&24&t&&(t&=-25),c=t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),Le((h?co:yo)(c,i),n,t)}function ce(n,t,r,e){return n===T||lu(n,ei[r])&&!oi.call(e,r)?t:n}function ae(n,t,r,e,u,i){return du(n)&&du(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return xu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;
+}else{if(f=new Zn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!du(n)||ci&&ci in n)&&(_u(n)?hi:dn).test(Te(n))}function Nt(n){return yu(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return yu(n)&&"[object Set]"==vo(n)}function Zt(n){return yu(n)&&gu(n.length)&&!!Bn[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?$u:typeof n=="object"?ff(n)?Jt(n[0],n[1]):Ht(n):Zu(n)}function Vt(n){if(!ze(n))return Li(n);var t,r=[];for(t in Qu(n))oi.call(n,t)&&"constructor"!=t&&r.push(t);
+return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=su(n)?Ku(n.length):[];return uo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!du(t)?We(Me(n),t):function(r){var e=Ru(r,n);return e===T&&e===t?zu(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&oo(t,function(i,o){if(u||(u=new Zn),du(i)){var f=u,c=Le(n,o),a=Le(t,o),l=f.get(a);if(l)it(n,o,l);else{
+var l=e?e(c,a,o+"",n,t,f):T,s=l===T;if(s){var h=ff(a),p=!h&&af(a),_=!h&&!p&&_f(a),l=a;h||p||_?ff(c)?l=c:hu(c)?l=Ur(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:xu(a)||of(a)?(l=c,of(c)?l=Ou(c):du(c)&&!_u(c)||(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a)),it(n,o,l)}}else f=e?e(Le(n,o),i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Bu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[$u],k(ye())),n=Gt(n,function(n){return{
+a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return zu(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=kt(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return kt(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;for(n===t&&(t=Ur(t)),
+r&&(f=c(n,k(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&xi.call(f,a,1),xi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?xi.call(n,u,1):xr(n,u)}}}function ir(n,t){return n+Ii(Ti()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Ii(t/2))&&(n+=n);while(t);return r}function fr(n,t){return xo(Be(n,t,$u),n+"")}function cr(n){return Qn(Uu(n))}function ar(n,t){var r=Uu(n);
+return De(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!du(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=Me(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=du(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return De(Uu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Ku(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return uo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}
+function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!wu(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return vr(n,t,$u,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=wu(t),a=t===T;u<i;){var l=Ii((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=wu(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ci(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){
+var o=n[r],f=t?t(o):o;if(!r||!lu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:wu(n)?F:+n}function yr(n){if(typeof n=="string")return n;if(ff(n))return c(n,yr)+"";if(wu(n))return ro?ro.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:so(n))return U(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;
+t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),n=2>t.length?n:kt(n,hr(t,0,-1)),null==n||delete n[Me(Ve(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Un&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Ku(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));
+return br(wt(i,1),t,r)}function Ar(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function Er(n){return hu(n)?n:[]}function kr(n){return typeof n=="function"?n:$u}function Sr(n,t){return ff(n)?n:Ie(n,t)?[n]:jo(Iu(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=gi?gi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new vi(t).set(new vi(n)),
+t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=wu(n),o=t!==T,f=null===t,c=t===t,a=wu(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Br(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Ui(i-o,0),l=Ku(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];
+return l}function Lr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Ui(i-f,0),s=Ku(l+a);for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Ur(n,t){var r=-1,e=n.length;for(t||(t=Ku(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,po(n),t)}function Mr(n,t){return Cr(n,_o(n),t);
+}function Tr(n,r){return function(e,u){var i=ff(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o)}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Qu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!su(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Qu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){
+var u=-1,i=Qu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break}return t}}function Pr(n,t,r){function e(){return(this&&this!==$n&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Iu(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Mu(Du(t).replace(kn,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){
+case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=eo(n.prototype),t=n.apply(r,t);return du(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Ku(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:L(f,a),
+o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==$n&&this instanceof u?i:t,this,f)}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Qu(t);if(!su(t)){var i=ye(r,3);t=Wu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ti("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?ho(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
+return function(){var n=arguments,e=n[0];if(o&&1==n.length&&ff(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Ku(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Br(y,e,u,_)),i&&(y=Lr(y,i,o,_)),d-=x,_&&d<a)return j=L(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ci(f.length,x),m=Ur(y);w--;){
+var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==$n&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Bt(r,n,t(e))}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
+return r=c(r,k(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Oi(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Ku(l+c),h=this&&this!==$n&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
+e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=Au(t),r===T?(r=t,t=0):r=Au(r),e=e===T?t<r?1:-1:Au(e);var u=-1;r=Ui(Oi((r-t)/(e||1)),0);for(var i=Ku(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Su(t),r=Su(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&yo(r,u),r.placeholder=e,Ue(r,n,t)}function ie(n){
+var t=Yu[n];return function(n,r){if(n=Su(n),(r=null==r?0:Ci(Eu(r),292))&&Wi(n)){var e=(Iu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Iu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=vo(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):E(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ti("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Ui(Eu(o),0),f=f===T?f:Eu(f),a-=u?u.length:0,
+64&t){var l=e,s=u;e=u=T}var h=c?T:ho(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ci(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],
+t=i[1],r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Ui(i[9]-a,0),!f&&24&t&&(t&=-25),Ue((h?co:yo)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||lu(n,ei[r])&&!oi.call(e,r)?t:n}function ae(n,t,r,e,u,i){return du(n)&&du(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return xu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;
var c=-1,a=true,l=2&r?new Nn:T;for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],p=t[c];if(e)var _=o?e(p,s,c,t,n,i):e(s,p,c,n,t,i);if(_!==T){if(_)continue;a=false;break}if(l){if(!h(t,function(n,t){if(!O(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==p&&!u(s,p,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function he(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":
-if(n.byteLength!=t.byteLength||!i(new vi(n),new vi(t)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return lu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=L),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(to)return to.call(n)==to.call(t)}
-return false}function pe(n){return xo(Ue(n,T,Ze),n+"")}function _e(n){return St(n,Wu,po)}function ve(n){return St(n,Uu,_o)}function ge(n){for(var t=n.name+"",r=Gi[t],e=oi.call(Gi,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(oi.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||Fu,n=n===Fu?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
+if(n.byteLength!=t.byteLength||!i(new vi(n),new vi(t)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return lu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=U),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(to)return to.call(n)==to.call(t)}
+return false}function pe(n){return xo(Be(n,T,Ze),n+"")}function _e(n){return St(n,Wu,po)}function ve(n){return St(n,Bu,_o)}function ge(n){for(var t=n.name+"",r=Gi[t],e=oi.call(Gi,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(oi.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||Fu,n=n===Fu?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
}function xe(n){for(var t=Wu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!du(u)]}return t}function je(n,t){var r=null==n?T:n[t];return Ft(r)?r:T}function we(n,t,r){t=Sr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=Me(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&gu(u)&&Se(o,u)&&(ff(n)||of(n)))}function me(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&oi.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ae(n){
-return typeof n.constructor!="function"||ze(n)?{}:eo(di(n))}function ke(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
-case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return to?Qu(to.call(n)):{}}}function Ee(n){return ff(n)||of(n)||!!(ji&&n&&n[ji])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
-}function Oe(n,t,r){if(!du(r))return false;var e=typeof t;return!!("number"==e?su(r)&&Se(t,r.length):"string"==e&&t in r)&&lu(r[t],n)}function Ie(n,t){if(ff(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!wu(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Qu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Ln.prototype&&(n===r||(t=ho(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ei)}function We(n,t){
-return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Qu(r)))}}function Ue(t,r,e){return r=Li(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Li(u.length-r,0),f=Ku(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Ku(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Be(n,t){if("__proto__"!=t)return n[t]}function Le(n,t,r){var e=t+"";t=xo;var u,i=$e;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),
-t(n,e)}function Ce(n){var t=0,r=0;return function(){var e=Di(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function De(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function Me(n){if(typeof n=="string"||wu(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Te(n){if(null!=n){try{return ii.call(n)}catch(n){}return n+""}return""}function $e(n,t){return r(N,function(r){var e="_."+r[0];
-t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function Fe(n){if(n instanceof Ln)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Lr(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ne(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:ku(r),0>r&&(r=Li(e+r,0)),_(n,ye(t,3),r)):-1}function Pe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=ku(r),u=0>r?Li(e+u,0):Ci(u,e-1)),_(n,ye(t,3),u,true)}function Ze(n){return(null==n?0:n.length)?wt(n,1):[];
-}function qe(n){return n&&n.length?n[0]:T}function Ve(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ke(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ge(n){return null==n?n:$i.call(n)}function He(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(hu(n))return t=Li(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function Je(t,r){if(!t||!t.length)return[];var e=He(t);return null==r?e:c(e,function(t){return n(r,T,t)})}function Ye(n){return n=An(n),n.__chain__=true,n;
-}function Qe(n,t){return t(n)}function Xe(){return this}function nu(n,t){return(ff(n)?r:uo)(n,ye(t,3))}function tu(n,t){return(ff(n)?e:io)(n,ye(t,3))}function ru(n,t){return(ff(n)?c:Gt)(n,ye(t,3))}function eu(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function uu(n,t){var r;if(typeof t!="function")throw new ti("Expected a function");return n=ku(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),r}}function iu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=iu.placeholder,
-n}function ou(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=ou.placeholder,n}function fu(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Go();if(u(n))return o(n);var r,e=bo;r=n-_,n=t-(n-p),r=g?Ci(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Go(),r=u(n);if(c=arguments,a=this,p=n,r){if(h===T)return _=n=p,h=bo(i,t),v?e(n):s;if(g)return h=bo(i,t),e(p)}return h===T&&(h=bo(i,t)),
-s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ti("Expected a function");return t=Su(t)||0,du(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Li(Su(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&lo(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Go())},f}function cu(n,t){if(typeof n!="function"||null!=t&&typeof t!="function")throw new ti("Expected a function");var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),
-r.cache=i.set(u,e)||i,e)};return r.cache=new(cu.Cache||Fn),r}function au(n){if(typeof n!="function")throw new ti("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function lu(n,t){return n===t||n!==n&&t!==t}function su(n){return null!=n&&gu(n.length)&&!_u(n)}function hu(n){return yu(n)&&su(n)}function pu(n){if(!yu(n))return false;
-var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!xu(n)}function _u(n){return!!du(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function vu(n){return typeof n=="number"&&n==ku(n)}function gu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n}function du(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function yu(n){return null!=n&&typeof n=="object";
-}function bu(n){return typeof n=="number"||yu(n)&&"[object Number]"==Ot(n)}function xu(n){return!(!yu(n)||"[object Object]"!=Ot(n))&&(n=di(n),null===n||(n=oi.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ii.call(n)==li))}function ju(n){return typeof n=="string"||!ff(n)&&yu(n)&&"[object String]"==Ot(n)}function wu(n){return typeof n=="symbol"||yu(n)&&"[object Symbol]"==Ot(n)}function mu(n){if(!n)return[];if(su(n))return ju(n)?M(n):Lr(n);if(wi&&n[wi]){n=n[wi]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);
-return r}return t=vo(n),("[object Map]"==t?W:"[object Set]"==t?L:Lu)(n)}function Au(n){return n?(n=Su(n),n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function ku(n){n=Au(n);var t=n%1;return n===n?t?n-t:n:0}function Eu(n){return n?pt(ku(n),0,4294967295):0}function Su(n){if(typeof n=="number")return n;if(wu(n))return F;if(du(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=du(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n;
-}function Ou(n){return Cr(n,Uu(n))}function Iu(n){return null==n?"":yr(n)}function Ru(n,t,r){return n=null==n?T:Et(n,t),n===T?r:n}function zu(n,t){return null!=n&&we(n,t,zt)}function Wu(n){return su(n)?qn(n):Vt(n)}function Uu(n){if(su(n))n=qn(n,true);else if(du(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&oi.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in Qu(n))t.push(r);n=t}return n}function Bu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){
-return t(n,r[0])})}function Lu(n){return null==n?[]:S(n,Wu(n))}function Cu(n){return $f(Iu(n).toLowerCase())}function Du(n){return(n=Iu(n))&&n.replace(xn,Xn).replace(Sn,"")}function Mu(n,t,r){return n=Iu(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Tu(n){return function(){return n}}function $u(n){return n}function Fu(n){return qt(typeof n=="function"?n:_t(n,1))}function Nu(n,t,e){var u=Wu(t),i=kt(t,u);null!=e||du(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=kt(t,Wu(t)));
-var o=!(du(e)&&"chain"in e&&!e.chain),f=_u(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Lr(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Pu(){}function Zu(n){return Ie(n)?b(Me(n)):rr(n)}function qu(){return[]}function Vu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Ku=mn.Array,Gu=mn.Date,Hu=mn.Error,Ju=mn.Function,Yu=mn.Math,Qu=mn.Object,Xu=mn.RegExp,ni=mn.String,ti=mn.TypeError,ri=Ku.prototype,ei=Qu.prototype,ui=mn["__core-js_shared__"],ii=Ju.prototype.toString,oi=ei.hasOwnProperty,fi=0,ci=function(){
-var n=/[^.]+$/.exec(ui&&ui.keys&&ui.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ai=ei.toString,li=ii.call(Qu),si=$n._,hi=Xu("^"+ii.call(oi).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),pi=Pn?mn.Buffer:T,_i=mn.Symbol,vi=mn.Uint8Array,gi=pi?pi.allocUnsafe:T,di=U(Qu.getPrototypeOf,Qu),yi=Qu.create,bi=ei.propertyIsEnumerable,xi=ri.splice,ji=_i?_i.isConcatSpreadable:T,wi=_i?_i.iterator:T,mi=_i?_i.toStringTag:T,Ai=function(){try{var n=je(Qu,"defineProperty");
-return n({},"",{}),n}catch(n){}}(),ki=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,Ei=Gu&&Gu.now!==$n.Date.now&&Gu.now,Si=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Oi=Yu.ceil,Ii=Yu.floor,Ri=Qu.getOwnPropertySymbols,zi=pi?pi.isBuffer:T,Wi=mn.isFinite,Ui=ri.join,Bi=U(Qu.keys,Qu),Li=Yu.max,Ci=Yu.min,Di=Gu.now,Mi=mn.parseInt,Ti=Yu.random,$i=ri.reverse,Fi=je(mn,"DataView"),Ni=je(mn,"Map"),Pi=je(mn,"Promise"),Zi=je(mn,"Set"),qi=je(mn,"WeakMap"),Vi=je(Qu,"create"),Ki=qi&&new qi,Gi={},Hi=Te(Fi),Ji=Te(Ni),Yi=Te(Pi),Qi=Te(Zi),Xi=Te(qi),no=_i?_i.prototype:T,to=no?no.valueOf:T,ro=no?no.toString:T,eo=function(){
-function n(){}return function(t){return du(t)?yi?yi(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=kn.prototype,An.prototype.constructor=An,On.prototype=eo(kn.prototype),On.prototype.constructor=On,Ln.prototype=eo(kn.prototype),Ln.prototype.constructor=Ln,Mn.prototype.clear=function(){this.__data__=Vi?Vi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
+return typeof n.constructor!="function"||ze(n)?{}:eo(di(n))}function Ee(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
+case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return to?Qu(to.call(n)):{}}}function ke(n){return ff(n)||of(n)||!!(ji&&n&&n[ji])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
+}function Oe(n,t,r){if(!du(r))return false;var e=typeof t;return!!("number"==e?su(r)&&Se(t,r.length):"string"==e&&t in r)&&lu(r[t],n)}function Ie(n,t){if(ff(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!wu(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Qu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Un.prototype&&(n===r||(t=ho(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ei)}function We(n,t){
+return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Qu(r)))}}function Be(t,r,e){return r=Ui(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Ui(u.length-r,0),f=Ku(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Ku(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Le(n,t){if(("constructor"!==t||"function"!=typeof n[t])&&"__proto__"!=t)return n[t]}function Ue(n,t,r){var e=t+"";t=xo;var u,i=$e;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],
+r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Ce(n){var t=0,r=0;return function(){var e=Di(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function De(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function Me(n){if(typeof n=="string"||wu(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Te(n){if(null!=n){try{return ii.call(n)}catch(n){}
+return n+""}return""}function $e(n,t){return r(N,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function Fe(n){if(n instanceof Un)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Ur(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ne(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),_(n,ye(t,3),r)):-1}function Pe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Eu(r),u=0>r?Ui(e+u,0):Ci(u,e-1)),
+_(n,ye(t,3),u,true)}function Ze(n){return(null==n?0:n.length)?wt(n,1):[]}function qe(n){return n&&n.length?n[0]:T}function Ve(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ke(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ge(n){return null==n?n:$i.call(n)}function He(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(hu(n))return t=Ui(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function Je(t,r){if(!t||!t.length)return[];var e=He(t);return null==r?e:c(e,function(t){
+return n(r,T,t)})}function Ye(n){return n=An(n),n.__chain__=true,n}function Qe(n,t){return t(n)}function Xe(){return this}function nu(n,t){return(ff(n)?r:uo)(n,ye(t,3))}function tu(n,t){return(ff(n)?e:io)(n,ye(t,3))}function ru(n,t){return(ff(n)?c:Gt)(n,ye(t,3))}function eu(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function uu(n,t){var r;if(typeof t!="function")throw new ti("Expected a function");return n=Eu(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),
+r}}function iu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=ou.placeholder,n}function fu(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Go();if(u(n))return o(n);var r,e=bo;r=n-_,n=t-(n-p),r=g?Ci(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Go(),r=u(n);if(c=arguments,
+a=this,p=n,r){if(h===T)return _=n=p,h=bo(i,t),v?e(n):s;if(g)return lo(h),h=bo(i,t),e(p)}return h===T&&(h=bo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ti("Expected a function");return t=Su(t)||0,du(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Ui(Su(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&lo(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Go())},f}function cu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;
+return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ti("Expected a function");return r.cache=new(cu.Cache||Fn),r}function au(n){if(typeof n!="function")throw new ti("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function lu(n,t){return n===t||n!==n&&t!==t;
+}function su(n){return null!=n&&gu(n.length)&&!_u(n)}function hu(n){return yu(n)&&su(n)}function pu(n){if(!yu(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!xu(n)}function _u(n){return!!du(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function vu(n){return typeof n=="number"&&n==Eu(n)}function gu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n;
+}function du(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function yu(n){return null!=n&&typeof n=="object"}function bu(n){return typeof n=="number"||yu(n)&&"[object Number]"==Ot(n)}function xu(n){return!(!yu(n)||"[object Object]"!=Ot(n))&&(n=di(n),null===n||(n=oi.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ii.call(n)==li))}function ju(n){return typeof n=="string"||!ff(n)&&yu(n)&&"[object String]"==Ot(n)}function wu(n){return typeof n=="symbol"||yu(n)&&"[object Symbol]"==Ot(n);
+}function mu(n){if(!n)return[];if(su(n))return ju(n)?M(n):Ur(n);if(wi&&n[wi]){n=n[wi]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=vo(n),("[object Map]"==t?W:"[object Set]"==t?U:Uu)(n)}function Au(n){return n?(n=Su(n),n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Eu(n){n=Au(n);var t=n%1;return n===n?t?n-t:n:0}function ku(n){return n?pt(Eu(n),0,4294967295):0}function Su(n){if(typeof n=="number")return n;if(wu(n))return F;if(du(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,
+n=du(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Ou(n){return Cr(n,Bu(n))}function Iu(n){return null==n?"":yr(n)}function Ru(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function zu(n,t){return null!=n&&we(n,t,zt)}function Wu(n){return su(n)?qn(n):Vt(n)}function Bu(n){if(su(n))n=qn(n,true);else if(du(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&oi.call(n,t))&&e.push(t);n=e}else{if(t=[],
+null!=n)for(r in Qu(n))t.push(r);n=t}return n}function Lu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Uu(n){return null==n?[]:S(n,Wu(n))}function Cu(n){return $f(Iu(n).toLowerCase())}function Du(n){return(n=Iu(n))&&n.replace(xn,Xn).replace(Sn,"")}function Mu(n,t,r){return n=Iu(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Tu(n){return function(){return n}}function $u(n){return n;
+}function Fu(n){return qt(typeof n=="function"?n:_t(n,1))}function Nu(n,t,e){var u=Wu(t),i=Et(t,u);null!=e||du(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,Wu(t)));var o=!(du(e)&&"chain"in e&&!e.chain),f=_u(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Pu(){}
+function Zu(n){return Ie(n)?b(Me(n)):rr(n)}function qu(){return[]}function Vu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Ku=mn.Array,Gu=mn.Date,Hu=mn.Error,Ju=mn.Function,Yu=mn.Math,Qu=mn.Object,Xu=mn.RegExp,ni=mn.String,ti=mn.TypeError,ri=Ku.prototype,ei=Qu.prototype,ui=mn["__core-js_shared__"],ii=Ju.prototype.toString,oi=ei.hasOwnProperty,fi=0,ci=function(){var n=/[^.]+$/.exec(ui&&ui.keys&&ui.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ai=ei.toString,li=ii.call(Qu),si=$n._,hi=Xu("^"+ii.call(oi).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),pi=Pn?mn.Buffer:T,_i=mn.Symbol,vi=mn.Uint8Array,gi=pi?pi.g:T,di=B(Qu.getPrototypeOf,Qu),yi=Qu.create,bi=ei.propertyIsEnumerable,xi=ri.splice,ji=_i?_i.isConcatSpreadable:T,wi=_i?_i.iterator:T,mi=_i?_i.toStringTag:T,Ai=function(){
+try{var n=je(Qu,"defineProperty");return n({},"",{}),n}catch(n){}}(),Ei=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,ki=Gu&&Gu.now!==$n.Date.now&&Gu.now,Si=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Oi=Yu.ceil,Ii=Yu.floor,Ri=Qu.getOwnPropertySymbols,zi=pi?pi.isBuffer:T,Wi=mn.isFinite,Bi=ri.join,Li=B(Qu.keys,Qu),Ui=Yu.max,Ci=Yu.min,Di=Gu.now,Mi=mn.parseInt,Ti=Yu.random,$i=ri.reverse,Fi=je(mn,"DataView"),Ni=je(mn,"Map"),Pi=je(mn,"Promise"),Zi=je(mn,"Set"),qi=je(mn,"WeakMap"),Vi=je(Qu,"create"),Ki=qi&&new qi,Gi={},Hi=Te(Fi),Ji=Te(Ni),Yi=Te(Pi),Qi=Te(Zi),Xi=Te(qi),no=_i?_i.prototype:T,to=no?no.valueOf:T,ro=no?no.toString:T,eo=function(){
+function n(){}return function(t){return du(t)?yi?yi(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=eo(En.prototype),On.prototype.constructor=On,Un.prototype=eo(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=Vi?Vi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return Vi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):oi.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return Vi?t[n]!==T:oi.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Vi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():xi.call(t,n,1),
--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1<ft(this.__data__,n)},Tn.prototype.set=function(n,t){var r=this.__data__,e=ft(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Ni||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n);
},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){
-return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Ni||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var uo=Fr(mt),io=Fr(At,true),oo=Nr(),fo=Nr(true),co=Ki?function(n,t){return Ki.set(n,t),n}:$u,ao=Ai?function(n,t){return Ai(n,"toString",{configurable:true,enumerable:false,value:Tu(t),writable:true})}:$u,lo=ki||function(n){
-return $n.clearTimeout(n)},so=Zi&&1/L(new Zi([,-0]))[1]==$?function(n){return new Zi(n)}:Pu,ho=Ki?function(n){return Ki.get(n)}:Pu,po=Ri?function(n){return null==n?[]:(n=Qu(n),i(Ri(n),function(t){return bi.call(n,t)}))}:qu,_o=Ri?function(n){for(var t=[];n;)a(t,po(n)),n=di(n);return t}:qu,vo=Ot;(Fi&&"[object DataView]"!=vo(new Fi(new ArrayBuffer(1)))||Ni&&"[object Map]"!=vo(new Ni)||Pi&&"[object Promise]"!=vo(Pi.resolve())||Zi&&"[object Set]"!=vo(new Zi)||qi&&"[object WeakMap]"!=vo(new qi))&&(vo=function(n){
+return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Ni||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var uo=Fr(mt),io=Fr(At,true),oo=Nr(),fo=Nr(true),co=Ki?function(n,t){return Ki.set(n,t),n}:$u,ao=Ai?function(n,t){return Ai(n,"toString",{configurable:true,enumerable:false,value:Tu(t),writable:true})}:$u,lo=Ei||function(n){
+return $n.clearTimeout(n)},so=Zi&&1/U(new Zi([,-0]))[1]==$?function(n){return new Zi(n)}:Pu,ho=Ki?function(n){return Ki.get(n)}:Pu,po=Ri?function(n){return null==n?[]:(n=Qu(n),i(Ri(n),function(t){return bi.call(n,t)}))}:qu,_o=Ri?function(n){for(var t=[];n;)a(t,po(n)),n=di(n);return t}:qu,vo=Ot;(Fi&&"[object DataView]"!=vo(new Fi(new ArrayBuffer(1)))||Ni&&"[object Map]"!=vo(new Ni)||Pi&&"[object Promise]"!=vo(Pi.resolve())||Zi&&"[object Set]"!=vo(new Zi)||qi&&"[object WeakMap]"!=vo(new qi))&&(vo=function(n){
var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Te(n):"")switch(n){case Hi:return"[object DataView]";case Ji:return"[object Map]";case Yi:return"[object Promise]";case Qi:return"[object Set]";case Xi:return"[object WeakMap]"}return t});var go=ui?_u:Vu,yo=Ce(co),bo=Si||function(n,t){return $n.setTimeout(n,t)},xo=Ce(ao),jo=function(n){n=cu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){
-t.push(e?u.replace(hn,"$1"):r||n)}),t}),wo=fr(function(n,t){return hu(n)?yt(n,wt(t,1,hu,true)):[]}),mo=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),ye(r,2)):[]}),Ao=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),T,r):[]}),ko=fr(function(n){var t=c(n,kr);return t.length&&t[0]===n[0]?Wt(t):[]}),Eo=fr(function(n){var t=Ve(n),r=c(n,kr);return t===Ve(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),So=fr(function(n){var t=Ve(n),r=c(n,kr);return(t=typeof t=="function"?t:T)&&r.pop(),
-r.length&&r[0]===n[0]?Wt(r,T,t):[]}),Oo=fr(Ke),Io=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Ro=fr(function(n){return br(wt(n,1,hu,true))}),zo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),br(wt(n,1,hu,true),ye(t,2))}),Wo=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return br(wt(n,1,hu,true),T,t)}),Uo=fr(function(n,t){return hu(n)?yt(n,t):[]}),Bo=fr(function(n){return mr(i(n,hu))}),Lo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),
-mr(i(n,hu),ye(t,2))}),Co=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return mr(i(n,hu),T,t)}),Do=fr(He),Mo=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return Je(n,t)}),To=pe(function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,u=function(t){return ht(t,n)};return!(1<t||this.__actions__.length)&&e instanceof Ln&&Se(r)?(e=e.slice(r,+r+(t?1:0)),e.__actions__.push({func:Qe,args:[u],thisArg:T}),new On(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(T),
-n})):this.thru(u)}),$o=Tr(function(n,t,r){oi.call(n,r)?++n[r]:st(n,r,1)}),Fo=Gr(Ne),No=Gr(Pe),Po=Tr(function(n,t,r){oi.call(n,r)?n[r].push(t):st(n,r,[t])}),Zo=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=su(t)?Ku(t.length):[];return uo(t,function(t){o[++u]=i?n(r,t,e):Bt(t,r,e)}),o}),qo=Tr(function(n,t,r){st(n,r,t)}),Vo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ko=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
-Xt(n,wt(t,1),[])}),Go=Ei||function(){return $n.Date.now()},Ho=fr(function(n,t,r){var e=1;if(r.length)var u=B(r,de(Ho)),e=32|e;return fe(n,e,t,r,u)}),Jo=fr(function(n,t,r){var e=3;if(r.length)var u=B(r,de(Jo)),e=32|e;return fe(t,e,n,r,u)}),Yo=fr(function(n,t){return dt(n,1,t)}),Qo=fr(function(n,t,r){return dt(n,Su(t)||0,r)});cu.Cache=Fn;var Xo=fr(function(t,r){r=1==r.length&&ff(r[0])?c(r[0],E(ye())):c(wt(r,1),E(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ci(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
-return n(t,this,u)})}),nf=fr(function(n,t){return fe(n,32,T,t,B(t,de(nf)))}),tf=fr(function(n,t){return fe(n,64,T,t,B(t,de(tf)))}),rf=pe(function(n,t){return fe(n,256,T,T,T,t)}),ef=ee(It),uf=ee(function(n,t){return n>=t}),of=Lt(function(){return arguments}())?Lt:function(n){return yu(n)&&oi.call(n,"callee")&&!bi.call(n,"callee")},ff=Ku.isArray,cf=Vn?E(Vn):Ct,af=zi||Vu,lf=Kn?E(Kn):Dt,sf=Gn?E(Gn):Tt,hf=Hn?E(Hn):Nt,pf=Jn?E(Jn):Pt,_f=Yn?E(Yn):Zt,vf=ee(Kt),gf=ee(function(n,t){return n<=t}),df=$r(function(n,t){
-if(ze(t)||su(t))Cr(t,Wu(t),n);else for(var r in t)oi.call(t,r)&&ot(n,r,t[r])}),yf=$r(function(n,t){Cr(t,Uu(t),n)}),bf=$r(function(n,t,r,e){Cr(t,Uu(t),n,e)}),xf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),jf=pe(ht),wf=fr(function(n,t){n=Qu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Uu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||lu(a,ei[c])&&!oi.call(n,c))&&(n[c]=u[c])}return n}),mf=fr(function(t){return t.push(T,ae),n(Of,T,t)}),Af=Yr(function(n,t,r){
-null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),n[t]=r},Tu($u)),kf=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),oi.call(n,t)?n[t].push(r):n[t]=[r]},ye),Ef=fr(Bt),Sf=$r(function(n,t,r){Yt(n,t,r)}),Of=$r(function(n,t,r,e){Yt(n,t,r,e)}),If=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),Rf=pe(function(n,t){return null==n?{}:nr(n,t);
-}),zf=oe(Wu),Wf=oe(Uu),Uf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Cu(t):t)}),Bf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Lf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Cf=Zr("toLowerCase"),Df=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Mf=qr(function(n,t,r){return n+(r?" ":"")+$f(t)}),Tf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),$f=Zr("toUpperCase"),Ff=fr(function(t,r){try{return n(t,T,r)}catch(n){return pu(n)?n:new Hu(n)}}),Nf=pe(function(n,t){
-return r(t,function(t){t=Me(t),st(n,t,Ho(n[t],n))}),n}),Pf=Hr(),Zf=Hr(true),qf=fr(function(n,t){return function(r){return Bt(r,n,t)}}),Vf=fr(function(n,t){return function(r){return Bt(n,r,t)}}),Kf=Xr(c),Gf=Xr(u),Hf=Xr(h),Jf=re(),Yf=re(true),Qf=Qr(function(n,t){return n+t},0),Xf=ie("ceil"),nc=Qr(function(n,t){return n/t},1),tc=ie("floor"),rc=Qr(function(n,t){return n*t},1),ec=ie("round"),uc=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ti("Expected a function");
-return n=ku(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=eu,An.assign=df,An.assignIn=yf,An.assignInWith=bf,An.assignWith=xf,An.at=jf,An.before=uu,An.bind=Ho,An.bindAll=Nf,An.bindKey=Jo,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ff(n)?n:[n]},An.chain=Ye,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Li(ku(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Ku(Oi(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
-var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Ku(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(ff(r)?Lr(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ti("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Tu,
-An.countBy=$o,An.create=function(n,t){var r=eo(n);return null==t?r:at(r,t)},An.curry=iu,An.curryRight=ou,An.debounce=fu,An.defaults=wf,An.defaultsDeep=mf,An.defer=Yo,An.delay=Qo,An.difference=wo,An.differenceBy=mo,An.differenceWith=Ao,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:ku(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:ku(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
-},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=ku(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:ku(e),0>e&&(e+=u),e=r>e?0:Eu(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(ff(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(ru(n,t),1)},An.flatMapDeep=function(n,t){return wt(ru(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:ku(r),
-wt(ru(n,t),r)},An.flatten=Ze,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:ku(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Pf,An.flowRight=Zf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:kt(n,Wu(n))},An.functionsIn=function(n){return null==n?[]:kt(n,Uu(n))},An.groupBy=Po,An.initial=function(n){
-return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=ko,An.intersectionBy=Eo,An.intersectionWith=So,An.invert=Af,An.invertBy=kf,An.invokeMap=Zo,An.iteratee=Fu,An.keyBy=qo,An.keys=Wu,An.keysIn=Uu,An.map=ru,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=cu,
-An.merge=Sf,An.mergeWith=Of,An.method=qf,An.methodOf=Vf,An.mixin=Nu,An.negate=au,An.nthArg=function(n){return n=ku(n),fr(function(t){return Qt(t,n)})},An.omit=If,An.omitBy=function(n,t){return Bu(n,au(ye(t)))},An.once=function(n){return uu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(ff(t)||(t=null==t?[]:[t]),r=e?T:r,ff(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Kf,An.overArgs=Xo,An.overEvery=Gf,An.overSome=Hf,An.partial=nf,An.partialRight=tf,An.partition=Vo,An.pick=Rf,An.pickBy=Bu,An.property=Zu,
-An.propertyOf=function(n){return function(t){return null==n?T:Et(n,t)}},An.pull=Oo,An.pullAll=Ke,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Io,An.range=Jf,An.rangeRight=Yf,An.rearg=rf,An.reject=function(n,t){return(ff(n)?i:jt)(n,au(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
-u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ti("Expected a function");return t=t===T?t:ku(t),fr(n,t)},An.reverse=Ge,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:ku(t),(ff(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(ff(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
-r=e):(t=null==t?0:ku(t),r=r===T?e:ku(r)),hr(n,t,r)):[]},An.sortBy=Ko,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Iu(n))&&(typeof t=="string"||null!=t&&!hf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ti("Expected a function");return r=null==r?0:Li(ku(r),0),
-fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:ku(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:ku(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
-n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ti("Expected a function");return du(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),fu(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Qe,An.toArray=mu,An.toPairs=zf,An.toPairsIn=Wf,An.toPath=function(n){return ff(n)?c(n,Me):wu(n)?[n]:Lr(jo(Iu(n)))},An.toPlainObject=Ou,An.transform=function(n,t,e){var u=ff(n),i=u||af(n)||_f(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:du(n)&&_u(o)?eo(di(n)):{};
-}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return eu(n,1)},An.union=Ro,An.unionBy=zo,An.unionWith=Wo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=He,An.unzipWith=Je,An.update=function(n,t,r){return null!=n&&(r=Er(r),n=lr(n,t,r(Et(n,t)),void 0)),n},An.updateWith=function(n,t,r,e){
-return e=typeof e=="function"?e:T,null!=n&&(r=Er(r),n=lr(n,t,r(Et(n,t)),e)),n},An.values=Lu,An.valuesIn=function(n){return null==n?[]:S(n,Uu(n))},An.without=Uo,An.words=Mu,An.wrap=function(n,t){return nf(Er(t),n)},An.xor=Bo,An.xorBy=Lo,An.xorWith=Co,An.zip=Do,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Mo,An.entries=zf,An.entriesIn=Wf,An.extend=yf,An.extendWith=bf,Nu(An,An),An.add=Qf,An.attempt=Ff,An.camelCase=Uf,An.capitalize=Cu,
+t.push(e?u.replace(hn,"$1"):r||n)}),t}),wo=fr(function(n,t){return hu(n)?yt(n,wt(t,1,hu,true)):[]}),mo=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),ye(r,2)):[]}),Ao=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),T,r):[]}),Eo=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),ko=fr(function(n){var t=Ve(n),r=c(n,Er);return t===Ve(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),So=fr(function(n){var t=Ve(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(),
+r.length&&r[0]===n[0]?Wt(r,T,t):[]}),Oo=fr(Ke),Io=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Ro=fr(function(n){return br(wt(n,1,hu,true))}),zo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),br(wt(n,1,hu,true),ye(t,2))}),Wo=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return br(wt(n,1,hu,true),T,t)}),Bo=fr(function(n,t){return hu(n)?yt(n,t):[]}),Lo=fr(function(n){return mr(i(n,hu))}),Uo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),
+mr(i(n,hu),ye(t,2))}),Co=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return mr(i(n,hu),T,t)}),Do=fr(He),Mo=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return Je(n,t)}),To=pe(function(n){function t(t){return ht(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Un&&Se(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(T),
+n})):this.thru(t)}),$o=Tr(function(n,t,r){oi.call(n,r)?++n[r]:st(n,r,1)}),Fo=Gr(Ne),No=Gr(Pe),Po=Tr(function(n,t,r){oi.call(n,r)?n[r].push(t):st(n,r,[t])}),Zo=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=su(t)?Ku(t.length):[];return uo(t,function(t){o[++u]=i?n(r,t,e):Lt(t,r,e)}),o}),qo=Tr(function(n,t,r){st(n,r,t)}),Vo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ko=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
+Xt(n,wt(t,1),[])}),Go=ki||function(){return $n.Date.now()},Ho=fr(function(n,t,r){var e=1;if(r.length)var u=L(r,de(Ho)),e=32|e;return fe(n,e,t,r,u)}),Jo=fr(function(n,t,r){var e=3;if(r.length)var u=L(r,de(Jo)),e=32|e;return fe(t,e,n,r,u)}),Yo=fr(function(n,t){return dt(n,1,t)}),Qo=fr(function(n,t,r){return dt(n,Su(t)||0,r)});cu.Cache=Fn;var Xo=fr(function(t,r){r=1==r.length&&ff(r[0])?c(r[0],k(ye())):c(wt(r,1),k(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ci(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
+return n(t,this,u)})}),nf=fr(function(n,t){return fe(n,32,T,t,L(t,de(nf)))}),tf=fr(function(n,t){return fe(n,64,T,t,L(t,de(tf)))}),rf=pe(function(n,t){return fe(n,256,T,T,T,t)}),ef=ee(It),uf=ee(function(n,t){return n>=t}),of=Ut(function(){return arguments}())?Ut:function(n){return yu(n)&&oi.call(n,"callee")&&!bi.call(n,"callee")},ff=Ku.isArray,cf=Vn?k(Vn):Ct,af=zi||Vu,lf=Kn?k(Kn):Dt,sf=Gn?k(Gn):Tt,hf=Hn?k(Hn):Nt,pf=Jn?k(Jn):Pt,_f=Yn?k(Yn):Zt,vf=ee(Kt),gf=ee(function(n,t){return n<=t}),df=$r(function(n,t){
+if(ze(t)||su(t))Cr(t,Wu(t),n);else for(var r in t)oi.call(t,r)&&ot(n,r,t[r])}),yf=$r(function(n,t){Cr(t,Bu(t),n)}),bf=$r(function(n,t,r,e){Cr(t,Bu(t),n,e)}),xf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),jf=pe(ht),wf=fr(function(n,t){n=Qu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Bu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||lu(a,ei[c])&&!oi.call(n,c))&&(n[c]=u[c])}return n}),mf=fr(function(t){return t.push(T,ae),n(Of,T,t)}),Af=Yr(function(n,t,r){
+null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),n[t]=r},Tu($u)),Ef=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),oi.call(n,t)?n[t].push(r):n[t]=[r]},ye),kf=fr(Lt),Sf=$r(function(n,t,r){Yt(n,t,r)}),Of=$r(function(n,t,r,e){Yt(n,t,r,e)}),If=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),Rf=pe(function(n,t){return null==n?{}:nr(n,t);
+}),zf=oe(Wu),Wf=oe(Bu),Bf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Cu(t):t)}),Lf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Uf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Cf=Zr("toLowerCase"),Df=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Mf=qr(function(n,t,r){return n+(r?" ":"")+$f(t)}),Tf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),$f=Zr("toUpperCase"),Ff=fr(function(t,r){try{return n(t,T,r)}catch(n){return pu(n)?n:new Hu(n)}}),Nf=pe(function(n,t){
+return r(t,function(t){t=Me(t),st(n,t,Ho(n[t],n))}),n}),Pf=Hr(),Zf=Hr(true),qf=fr(function(n,t){return function(r){return Lt(r,n,t)}}),Vf=fr(function(n,t){return function(r){return Lt(n,r,t)}}),Kf=Xr(c),Gf=Xr(u),Hf=Xr(h),Jf=re(),Yf=re(true),Qf=Qr(function(n,t){return n+t},0),Xf=ie("ceil"),nc=Qr(function(n,t){return n/t},1),tc=ie("floor"),rc=Qr(function(n,t){return n*t},1),ec=ie("round"),uc=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ti("Expected a function");
+return n=Eu(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=eu,An.assign=df,An.assignIn=yf,An.assignInWith=bf,An.assignWith=xf,An.at=jf,An.before=uu,An.bind=Ho,An.bindAll=Nf,An.bindKey=Jo,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ff(n)?n:[n]},An.chain=Ye,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Ui(Eu(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Ku(Oi(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
+var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Ku(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(ff(r)?Ur(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ti("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Tu,
+An.countBy=$o,An.create=function(n,t){var r=eo(n);return null==t?r:at(r,t)},An.curry=iu,An.curryRight=ou,An.debounce=fu,An.defaults=wf,An.defaultsDeep=mf,An.defer=Yo,An.delay=Qo,An.difference=wo,An.differenceBy=mo,An.differenceWith=Ao,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
+},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Eu(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Eu(e),0>e&&(e+=u),e=r>e?0:ku(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(ff(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(ru(n,t),1)},An.flatMapDeep=function(n,t){return wt(ru(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:Eu(r),
+wt(ru(n,t),r)},An.flatten=Ze,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:Eu(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Pf,An.flowRight=Zf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:Et(n,Wu(n))},An.functionsIn=function(n){return null==n?[]:Et(n,Bu(n))},An.groupBy=Po,An.initial=function(n){
+return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=Eo,An.intersectionBy=ko,An.intersectionWith=So,An.invert=Af,An.invertBy=Ef,An.invokeMap=Zo,An.iteratee=Fu,An.keyBy=qo,An.keys=Wu,An.keysIn=Bu,An.map=ru,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=cu,
+An.merge=Sf,An.mergeWith=Of,An.method=qf,An.methodOf=Vf,An.mixin=Nu,An.negate=au,An.nthArg=function(n){return n=Eu(n),fr(function(t){return Qt(t,n)})},An.omit=If,An.omitBy=function(n,t){return Lu(n,au(ye(t)))},An.once=function(n){return uu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(ff(t)||(t=null==t?[]:[t]),r=e?T:r,ff(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Kf,An.overArgs=Xo,An.overEvery=Gf,An.overSome=Hf,An.partial=nf,An.partialRight=tf,An.partition=Vo,An.pick=Rf,An.pickBy=Lu,An.property=Zu,
+An.propertyOf=function(n){return function(t){return null==n?T:kt(n,t)}},An.pull=Oo,An.pullAll=Ke,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Io,An.range=Jf,An.rangeRight=Yf,An.rearg=rf,An.reject=function(n,t){return(ff(n)?i:jt)(n,au(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
+u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ti("Expected a function");return t=t===T?t:Eu(t),fr(n,t)},An.reverse=Ge,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),(ff(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(ff(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
+r=e):(t=null==t?0:Eu(t),r=r===T?e:Eu(r)),hr(n,t,r)):[]},An.sortBy=Ko,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Iu(n))&&(typeof t=="string"||null!=t&&!hf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ti("Expected a function");return r=null==r?0:Ui(Eu(r),0),
+fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Eu(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
+n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ti("Expected a function");return du(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),fu(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Qe,An.toArray=mu,An.toPairs=zf,An.toPairsIn=Wf,An.toPath=function(n){return ff(n)?c(n,Me):wu(n)?[n]:Ur(jo(Iu(n)))},An.toPlainObject=Ou,An.transform=function(n,t,e){var u=ff(n),i=u||af(n)||_f(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:du(n)&&_u(o)?eo(di(n)):{};
+}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return eu(n,1)},An.union=Ro,An.unionBy=zo,An.unionWith=Wo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=He,An.unzipWith=Je,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){
+return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Uu,An.valuesIn=function(n){return null==n?[]:S(n,Bu(n))},An.without=Bo,An.words=Mu,An.wrap=function(n,t){return nf(kr(t),n)},An.xor=Lo,An.xorBy=Uo,An.xorWith=Co,An.zip=Do,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Mo,An.entries=zf,An.entriesIn=Wf,An.extend=yf,An.extendWith=bf,Nu(An,An),An.add=Qf,An.attempt=Ff,An.camelCase=Bf,An.capitalize=Cu,
An.ceil=Xf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=Su(r),r=r===r?r:0),t!==T&&(t=Su(t),t=t===t?t:0),pt(Su(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,Wu(t))},An.deburr=Du,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=nc,An.endsWith=function(n,t,r){
-n=Iu(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(ku(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=lu,An.escape=function(n){return(n=Iu(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Iu(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=ff(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=Fo,An.findIndex=Ne,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=No,An.findLastIndex=Pe,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
-},An.floor=tc,An.forEach=nu,An.forEachRight=tu,An.forIn=function(n,t){return null==n?n:oo(n,ye(t,3),Uu)},An.forInRight=function(n,t){return null==n?n:fo(n,ye(t,3),Uu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Ru,An.gt=ef,An.gte=uf,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=zu,An.head=qe,An.identity=$u,An.includes=function(n,t,r,e){return n=su(n)?n:Lu(n),r=r&&!e?ku(r):0,e=n.length,0>r&&(r=Li(e+r,0)),ju(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
-},An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:ku(r),0>r&&(r=Li(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=Au(t),r===T?(r=t,t=0):r=Au(r),n=Su(n),n>=Ci(t,r)&&n<Li(t,r)},An.invoke=Ef,An.isArguments=of,An.isArray=ff,An.isArrayBuffer=cf,An.isArrayLike=su,An.isArrayLikeObject=hu,An.isBoolean=function(n){return true===n||false===n||yu(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=af,An.isDate=lf,An.isElement=function(n){return yu(n)&&1===n.nodeType&&!xu(n)},An.isEmpty=function(n){
+n=Iu(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Eu(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=lu,An.escape=function(n){return(n=Iu(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Iu(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=ff(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=Fo,An.findIndex=Ne,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=No,An.findLastIndex=Pe,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
+},An.floor=tc,An.forEach=nu,An.forEachRight=tu,An.forIn=function(n,t){return null==n?n:oo(n,ye(t,3),Bu)},An.forInRight=function(n,t){return null==n?n:fo(n,ye(t,3),Bu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Ru,An.gt=ef,An.gte=uf,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=zu,An.head=qe,An.identity=$u,An.includes=function(n,t,r,e){return n=su(n)?n:Uu(n),r=r&&!e?Eu(r):0,e=n.length,0>r&&(r=Ui(e+r,0)),ju(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
+},An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=Au(t),r===T?(r=t,t=0):r=Au(r),n=Su(n),n>=Ci(t,r)&&n<Ui(t,r)},An.invoke=kf,An.isArguments=of,An.isArray=ff,An.isArrayBuffer=cf,An.isArrayLike=su,An.isArrayLikeObject=hu,An.isBoolean=function(n){return true===n||false===n||yu(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=af,An.isDate=lf,An.isElement=function(n){return yu(n)&&1===n.nodeType&&!xu(n)},An.isEmpty=function(n){
if(null==n)return true;if(su(n)&&(ff(n)||typeof n=="string"||typeof n.splice=="function"||af(n)||_f(n)||of(n)))return!n.length;var t=vo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(ze(n))return!Vt(n).length;for(var r in n)if(oi.call(n,r))return false;return true},An.isEqual=function(n,t){return Mt(n,t)},An.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:T)?r(n,t):T;return e===T?Mt(n,t,T,r):!!e},An.isError=pu,An.isFinite=function(n){return typeof n=="number"&&Wi(n)},An.isFunction=_u,
An.isInteger=vu,An.isLength=gu,An.isMap=sf,An.isMatch=function(n,t){return n===t||$t(n,t,xe(t))},An.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:T,$t(n,t,xe(t),r)},An.isNaN=function(n){return bu(n)&&n!=+n},An.isNative=function(n){if(go(n))throw new Hu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Ft(n)},An.isNil=function(n){return null==n},An.isNull=function(n){return null===n},An.isNumber=bu,An.isObject=du,An.isObjectLike=yu,An.isPlainObject=xu,An.isRegExp=hf,
-An.isSafeInteger=function(n){return vu(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=pf,An.isString=ju,An.isSymbol=wu,An.isTypedArray=_f,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return yu(n)&&"[object WeakMap]"==vo(n)},An.isWeakSet=function(n){return yu(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Ui.call(n,t)},An.kebabCase=Bf,An.last=Ve,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=ku(r),u=0>u?Li(e+u,0):Ci(u,e-1)),
-t===t)n:{for(r=u+1;r--;)if(n[r]===t){n=r;break n}n=r}else n=_(n,d,u,true);return n},An.lowerCase=Lf,An.lowerFirst=Cf,An.lt=vf,An.lte=gf,An.max=function(n){return n&&n.length?xt(n,$u,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,$u)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,$u,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=qu,An.stubFalse=Vu,An.stubObject=function(){
-return{}},An.stubString=function(){return""},An.stubTrue=function(){return true},An.multiply=rc,An.nth=function(n,t){return n&&n.length?Qt(n,ku(t)):T},An.noConflict=function(){return $n._===this&&($n._=si),this},An.noop=Pu,An.now=Go,An.pad=function(n,t,r){n=Iu(n);var e=(t=ku(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Ii(t),r)+n+ne(Oi(t),r))},An.padEnd=function(n,t,r){n=Iu(n);var e=(t=ku(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Iu(n);var e=(t=ku(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n;
-},An.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),Mi(Iu(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=Au(n),t===T?(t=n,n=0):t=Au(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Ti(),Ci(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=ff(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,uo)},An.reduceRight=function(n,t,r){
-var e=ff(n)?s:j,u=3>arguments.length;return e(n,ye(t,4),r,u,io)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:ku(t),or(Iu(n),t)},An.replace=function(){var n=arguments,t=Iu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[Me(t[e])];i===T&&(e=u,i=r),n=_u(i)?i.call(n):i}return n},An.round=ec,An.runInContext=x,An.sample=function(n){return(ff(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;
-if(su(n))return ju(n)?D(n):n.length;var t=vo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Df,An.some=function(n,t,r){var e=ff(n)?h:pr;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&lu(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){
-return vr(n,t,ye(r,2),true)},An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(lu(n[r],t))return r}return-1},An.startCase=Mf,An.startsWith=function(n,t,r){return n=Iu(n),r=null==r?0:pt(ku(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=uc,An.sum=function(n){return n&&n.length?m(n,$u):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Iu(n),t=bf({},t,e,ce),r=bf({},t.imports,e.imports,ce);
-var u,i,o=Wu(r),f=S(r,o),c=0;r=t.interpolate||jn;var a="__p+='";r=Xu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),
-a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Ff(function(){return Ju(o,l+"return "+a).apply(T,f)}),t.source=a,pu(t))throw t;return t},An.times=function(n,t){if(n=ku(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ci(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=Au,An.toInteger=ku,An.toLength=Eu,An.toLower=function(n){
-return Iu(n).toLowerCase()},An.toNumber=Su,An.toSafeInteger=function(n){return n?pt(ku(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Iu,An.toUpper=function(n){return Iu(n).toUpperCase()},An.trim=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){
-return(n=Iu(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(du(t))var u="separator"in t?t.separator:u,r="length"in t?ku(t.length):r,e="omission"in t?yr(t.omission):e;n=Iu(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),hf(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=Xu(u.source,Iu(_n.exec(u))+"g")),
-u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Iu(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++fi;return Iu(n)+t},An.upperCase=Tf,An.upperFirst=$f,An.each=nu,An.eachRight=tu,An.first=qe,Nu(An,function(){var n={};return mt(An,function(t,r){oi.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false}),An.VERSION="4.17.11",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){
-An[n].placeholder=An}),r(["drop","take"],function(n,t){Ln.prototype[n]=function(r){r=r===T?1:Li(ku(r),0);var e=this.__filtered__&&!t?new Ln(this):this.clone();return e.__filtered__?e.__takeCount__=Ci(r,e.__takeCount__):e.__views__.push({size:Ci(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Ln.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Ln.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({
-iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Ln.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Ln.prototype[n]=function(){return this.__filtered__?new Ln(this):this[r](1)}}),Ln.prototype.compact=function(){return this.filter($u)},Ln.prototype.find=function(n){return this.filter(n).head()},Ln.prototype.findLast=function(n){return this.reverse().find(n);
-},Ln.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Ln(this):this.map(function(r){return Bt(r,n,t)})}),Ln.prototype.reject=function(n){return this.filter(au(ye(n)))},Ln.prototype.slice=function(n,t){n=ku(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Ln(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=ku(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Ln.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Ln.prototype.toArray=function(){return this.take(4294967295);
-},mt(Ln.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){var t=this.__wrapped__,o=e?[1]:arguments,f=t instanceof Ln,c=o[0],l=f||ff(t),s=function(n){return n=u.apply(An,a([n],o)),e&&h?n[0]:n};l&&r&&typeof c=="function"&&1!=c.length&&(f=l=false);var h=this.__chain__,p=!!this.__actions__.length,c=i&&!h,f=f&&!p;return!i&&l?(t=f?t:new Ln(this),t=n.apply(t,o),t.__actions__.push({
-func:Qe,args:[s],thisArg:T}),new On(t,h)):c&&f?n.apply(this,o):(t=this.thru(s),c?e?t.value()[0]:t.value():t)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ri[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ff(u)?u:[],n)}return this[r](function(r){return t.apply(ff(r)?r:[],n)})}}),mt(Ln.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";
-(Gi[e]||(Gi[e]=[])).push({name:t,func:r})}}),Gi[Jr(T,2).name]=[{name:"wrapper",func:T}],Ln.prototype.clone=function(){var n=new Ln(this.__wrapped__);return n.__actions__=Lr(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Lr(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Lr(this.__views__),n},Ln.prototype.reverse=function(){if(this.__filtered__){var n=new Ln(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n;
-},Ln.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=ff(t),u=0>r,i=e?t.length:0;n=0;for(var o=i,f=this.__views__,c=-1,a=f.length;++c<a;){var l=f[c],s=l.size;switch(l.type){case"drop":n+=s;break;case"dropRight":o-=s;break;case"take":o=Ci(o,n+s);break;case"takeRight":n=Li(n,o-s)}}if(n={start:n,end:o},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ci(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);e=[];n:for(;n--&&a<l;){for(o+=r,
-u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=To,An.prototype.chain=function(){return Ye(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=mu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){for(var t,r=this;r instanceof kn;){
-var e=Fe(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Ln?(this.__actions__.length&&(n=new Ln(this)),n=n.reverse(),n.__actions__.push({func:Qe,args:[Ge],thisArg:T}),new On(n,this.__chain__)):this.thru(Ge)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,wi&&(An.prototype[wi]=Xe),
-An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this);
\ No newline at end of file
+An.isSafeInteger=function(n){return vu(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=pf,An.isString=ju,An.isSymbol=wu,An.isTypedArray=_f,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return yu(n)&&"[object WeakMap]"==vo(n)},An.isWeakSet=function(n){return yu(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Bi.call(n,t)},An.kebabCase=Lf,An.last=Ve,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Eu(r),u=0>u?Ui(e+u,0):Ci(u,e-1)),
+t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Uf,An.lowerFirst=Cf,An.lt=vf,An.lte=gf,An.max=function(n){return n&&n.length?xt(n,$u,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,$u)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,$u,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=qu,An.stubFalse=Vu,An.stubObject=function(){return{}},An.stubString=function(){
+return""},An.stubTrue=function(){return true},An.multiply=rc,An.nth=function(n,t){return n&&n.length?Qt(n,Eu(t)):T},An.noConflict=function(){return $n._===this&&($n._=si),this},An.noop=Pu,An.now=Go,An.pad=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Ii(t),r)+n+ne(Oi(t),r))},An.padEnd=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n},An.parseInt=function(n,t,r){
+return r||null==t?t=0:t&&(t=+t),Mi(Iu(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=Au(n),t===T?(t=n,n=0):t=Au(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Ti(),Ci(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=ff(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,uo)},An.reduceRight=function(n,t,r){var e=ff(n)?s:j,u=3>arguments.length;
+return e(n,ye(t,4),r,u,io)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),or(Iu(n),t)},An.replace=function(){var n=arguments,t=Iu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[Me(t[e])];i===T&&(e=u,i=r),n=_u(i)?i.call(n):i}return n},An.round=ec,An.runInContext=x,An.sample=function(n){return(ff(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;if(su(n))return ju(n)?D(n):n.length;
+var t=vo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Df,An.some=function(n,t,r){var e=ff(n)?h:pr;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&lu(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){return vr(n,t,ye(r,2),true);
+},An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(lu(n[r],t))return r}return-1},An.startCase=Mf,An.startsWith=function(n,t,r){return n=Iu(n),r=null==r?0:pt(Eu(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=uc,An.sum=function(n){return n&&n.length?m(n,$u):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Iu(n),t=bf({},t,e,ce),r=bf({},t.imports,e.imports,ce);var u,i,o=Wu(r),f=S(r,o),c=0;
+r=t.interpolate||jn;var a="__p+='";r=Xu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l=oi.call(t,"sourceURL")?"//# sourceURL="+(t.sourceURL+"").replace(/[\r\n]/g," ")+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=oi.call(t,"variable")&&t.variable)||(a="with(obj){"+a+"}"),
+a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Ff(function(){return Ju(o,l+"return "+a).apply(T,f)}),t.source=a,pu(t))throw t;return t},An.times=function(n,t){if(n=Eu(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ci(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=Au,
+An.toInteger=Eu,An.toLength=ku,An.toLower=function(n){return Iu(n).toLowerCase()},An.toNumber=Su,An.toSafeInteger=function(n){return n?pt(Eu(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Iu,An.toUpper=function(n){return Iu(n).toUpperCase()},An.trim=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,
+Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(du(t))var u="separator"in t?t.separator:u,r="length"in t?Eu(t.length):r,e="omission"in t?yr(t.omission):e;n=Iu(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),hf(u)){if(n.slice(i).search(u)){
+var f=r;for(u.global||(u=Xu(u.source,Iu(_n.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Iu(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++fi;return Iu(n)+t},An.upperCase=Tf,An.upperFirst=$f,An.each=nu,An.eachRight=tu,An.first=qe,Nu(An,function(){var n={};return mt(An,function(t,r){oi.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false
+}),An.VERSION="4.17.15",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){An[n].placeholder=An}),r(["drop","take"],function(n,t){Un.prototype[n]=function(r){r=r===T?1:Ui(Eu(r),0);var e=this.__filtered__&&!t?new Un(this):this.clone();return e.__filtered__?e.__takeCount__=Ci(r,e.__takeCount__):e.__views__.push({size:Ci(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){
+var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter($u)},Un.prototype.find=function(n){
+return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n)},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(au(ye(n)))},Un.prototype.slice=function(n,t){n=Eu(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Eu(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){
+return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295)},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||ff(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;
+return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ri[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ff(u)?u:[],n)}return this[r](function(r){return t.apply(ff(r)?r:[],n)});
+}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";oi.call(Gi,e)||(Gi[e]=[]),Gi[e].push({name:t,func:r})}}),Gi[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);
+n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=ff(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Ci(n,f+s);break;case"takeRight":f=Ui(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ci(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);
+e=[];n:for(;n--&&a<l;){for(o+=r,u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=To,An.prototype.chain=function(){return Ye(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=mu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){
+for(var t,r=this;r instanceof En;){var e=Fe(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Qe,args:[Ge],thisArg:T}),new On(n,this.__chain__)):this.thru(Ge)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,
+wi&&(An.prototype[wi]=Xe),An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this);
\ No newline at end of file
FLAG_FLASH_REPLACE_VF_MODULE: "FLAG_FLASH_REPLACE_VF_MODULE",
FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT: "FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT",
FLAG_SHOW_ORCHESTRATION_TYPE: "FLAG_SHOW_ORCHESTRATION_TYPE",
- FLAG_2004_INSTANTIATION_TEMPLATES_POPUP : "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP"
+ FLAG_2004_INSTANTIATION_TEMPLATES_POPUP : "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP",
+ FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY: "FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY"
}
};
$scope.reloadRoute();\r
} else {\r
color = FIELD.ID.COLOR_F88;\r
+ $scope.reloadRoute();\r
}\r
$scope.callbackStyle = {\r
"background-color": color\r
viewPerPage: $scope.viewPerPage,
currentPage: $scope.currentPage
};
- DataService.setHasTemplate(service.hasTemplate);
+ DataService.setIsInstantiationTemplateExists(service.isInstantiationTemplateExists);
sessionStorage.setItem("searchKey",JSON.stringify(searchKey));
console.log("Instantiating SDC service " + service.uuid);
{
$location.path('/servicePlanning').search({serviceModelId: event.data.data.serviceModelId});
}
- } else if (event.data.eventId == 'showPreviousInstantiations') {
- {
- $location.path('/instantiationStatus').search({filterText: event.data.data.serviceModelId});
- }
}
$scope.$apply();
}
if (!$scope.shouldShowOldPopup()) {
- if(DataService.getHasTemplate()){
- $scope.url = COMPONENT.INSTANTIATION_TEMPLATES_IFRAME_URL + request.modelNameVersionId;
+ let modelNameVersionId = request.modelNameVersionId ?
+ request.modelNameVersionId :
+ (DataService.getModelInfo(COMPONENT.SERVICE) ? DataService.getModelInfo(COMPONENT.SERVICE).modelNameVersionId : "");
+ if(DataService.getIsInstantiationTemplateExists()){
+ $scope.url = COMPONENT.INSTANTIATION_TEMPLATES_IFRAME_URL + modelNameVersionId;
window.addEventListener("message", receiveMessage, false);
}else {
- $scope.url = COMPONENT.SERVICE_POPUP_IFRAME_URL + request.modelNameVersionId + "&isCreate=true&r=" + Math.random();
+ $scope.url = COMPONENT.SERVICE_POPUP_IFRAME_URL + modelNameVersionId + "&isCreate=true&r=" + Math.random();
window.addEventListener("message", receiveMessage, false);
}
}
} else {
$scope.isDialogVisible = false;
$scope.popup.isVisible = false;
+ runCallback(response);
}
}
});
setOwningEntityProperties: function (properties) {
_this.owningEntityProperties = properties;
},
- getHasTemplate: function () {
- return _this.hasTemplate;
+ getIsInstantiationTemplateExists: function () {
+ return _this.isInstantiationTemplateExists;
},
- setHasTemplate: function (hasTemplate) {
- _this.hasTemplate = hasTemplate;
+ setIsInstantiationTemplateExists: function (isInstantiationTemplateExists) {
+ _this.isInstantiationTemplateExists = isInstantiationTemplateExists;
}
};
};
import org.onap.vid.roles.EcompRole;
import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleValidator;
+import org.onap.vid.roles.RoleValidatorFactory;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
public class SubscriberFilteredResultsTest {
}
private void prepareRoleValidator() {
- ArrayList<Role> list = new ArrayList<>();
- list.add(new Role(EcompRole.READ, "a", "a", "a"));
- roleValidator = RoleValidator.by(list);
+ roleValidator = mock(RoleValidator.class);
}
private void prepareSubscriberList() throws IOException {
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.bl;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.arrayWithSize;
-import static org.hamcrest.Matchers.equalTo;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.onap.vid.aai.AaiClientInterface;
-import org.onap.vid.aai.AaiResponse;
-import org.onap.vid.aai.model.AaiGetPnfResponse;
-import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
-import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
-import org.onap.vid.aai.model.LogicalLinkResponse;
-import org.onap.vid.aai.model.Relationship;
-import org.onap.vid.aai.model.RelationshipData;
-import org.onap.vid.aai.model.RelationshipList;
-import org.onap.vid.aai.model.ServiceRelationships;
-import org.onap.vid.roles.Role;
-import org.onap.vid.roles.RoleValidator;
-import org.onap.vid.services.AaiServiceImpl;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-public class AaiServiceTest {
-
- @InjectMocks
- private AaiServiceImpl aaiService;
-
- @Mock
- private AaiClientInterface aaiClientInterface;
-
-
-
- @BeforeMethod
- public void initMocks(){
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testGetSpecificPnf(){
- Pnf pnf = Pnf.builder().withPnfId("11111").build();
- AaiResponse<Pnf> aaiResponse = new AaiResponse<>(pnf, "aaaa", 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getSpecificPnf(Mockito.anyString());
- AaiResponse<Pnf> specificPnf = aaiService.getSpecificPnf("1345667");
- assertNotNull(specificPnf);
- pnf = specificPnf.getT();
- assertNotNull(pnf);
- assertEquals("11111",pnf.getPnfId());
- assertEquals("aaaa",specificPnf.getErrorMessage());
- assertEquals(200,specificPnf.getHttpCode());
- }
-
- @Test
- public void testPnfByRegion(){
- AaiGetPnfResponse aaiGetPnfResponse = new AaiGetPnfResponse();
- AaiResponse<AaiGetPnfResponse> aaiResponse = new AaiResponse<>(aaiGetPnfResponse, "", 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getPNFData(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
- AaiResponse<AaiGetPnfResponse> aaiGetPnfResponseWrapper = aaiService.getPNFData("1345667", "1345667", "1345667", "1345667", "1345667", "1345667", "1345667");
- assertNotNull(aaiGetPnfResponseWrapper);
- aaiGetPnfResponse = aaiGetPnfResponseWrapper.getT();
- assertNotNull(aaiGetPnfResponse);
- }
-
- @Test
- public void testGetAssociatedPnfs(){
- ServiceRelationships serviceRelationships = createServiceRelationships();
- AaiResponse<ServiceRelationships> aaiResponse = new AaiResponse<>(serviceRelationships, null, 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getServiceInstance(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
-
- LogicalLinkResponse logicalLinkResponse = createLogicalLinkResponse();
- AaiResponse<LogicalLinkResponse> aaiResponse1 = new AaiResponse<>(logicalLinkResponse, null, 200);
- Mockito.doReturn(aaiResponse1).when(aaiClientInterface).getLogicalLink("SANITY6758cce9%3ALAG1992%7CSANITY6785cce9%3ALAG1961");
-
- List<String> pnfList = aaiService.getServiceInstanceAssociatedPnfs("123", "456", "789");
- assertNotNull(pnfList);
- assertEquals(1, pnfList.size());
- assertEquals("SANITY6785cce9", pnfList.get(0));
- }
-
- private ServiceRelationships createServiceRelationships() {
- ServiceRelationships serviceRelationships = new ServiceRelationships();
- serviceRelationships.setServiceInstanceName("test service");
-
- RelationshipData logicalLinksRelationshipData = new RelationshipData();
- logicalLinksRelationshipData.setRelationshipKey("logical-link.link-name");
- logicalLinksRelationshipData.setRelationshipValue("SANITY6758cce9:LAG1992|SANITY6785cce9:LAG1961");
-
- Relationship logicalLinksRelationship = new Relationship();
- logicalLinksRelationship.setRelatedTo("logical-link");
- logicalLinksRelationship.setRelationDataList(Arrays.asList(logicalLinksRelationshipData));
-
- RelationshipList logicalLinksRelationshipsList = new RelationshipList();
- logicalLinksRelationshipsList.setRelationship(Arrays.asList(logicalLinksRelationship));
-
- serviceRelationships.setRelationshipList(logicalLinksRelationshipsList);
- return serviceRelationships;
- }
-
- private LogicalLinkResponse createLogicalLinkResponse() {
- LogicalLinkResponse logicalLinkResponse = new LogicalLinkResponse();
- logicalLinkResponse.setLinkName("SANITY6758cce9:LAG1992|SANITY6785cce9:LAG1961");
-
- RelationshipData lagInterfaceRelationshipData = new RelationshipData();
- lagInterfaceRelationshipData.setRelationshipKey("pnf.pnf-name");
- lagInterfaceRelationshipData.setRelationshipValue("SANITY6785cce9");
-
- Relationship lagInterfaceRelationship = new Relationship();
- lagInterfaceRelationship.setRelatedTo("lag-interface");
- lagInterfaceRelationship.setRelationDataList(Arrays.asList(lagInterfaceRelationshipData));
-
- RelationshipList lagInterfaceRelationshipsList = new RelationshipList();
- lagInterfaceRelationshipsList.setRelationship(Arrays.asList(lagInterfaceRelationship));
-
- logicalLinkResponse.setRelationshipList(lagInterfaceRelationshipsList);
-
- return logicalLinkResponse;
- }
-
- @DataProvider
- public static Object[][] getTenantsData() {
- return new Object[][] {
- {"customer1", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TeNant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TENANT1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "tenant2", "customer1", "serviceType1", "tenant1", "tenant2", false},
- {"customer1", "serviceType1", null, "customer1", "serviceType1", "tenant1", "tenant2", true},
- {"customer2", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", false},
- {"customer1", "serviceType2", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", false},
- {"customer2", "serviceType1", null, "customer1", "serviceType1", "tenant1", "id-1", false},
- {"customer1", "serviceType2", null, "customer1", "serviceType1", "tenant1", "id-1", false},
- };
- }
-
- @Test(dataProvider = "getTenantsData")
- public void testGetTenants(String userGlobalCustomerId, String userServiceType, String userTenantName, String serviceGlobalCustomerId,
- String serviceServiceType, String serviceTenantName, String serviceTenantId, boolean expectedIsPermitted) {
- GetTenantsResponse[] getTenantsResponses = new GetTenantsResponse[] {new GetTenantsResponse(null, null, serviceTenantName, serviceTenantId, expectedIsPermitted)};
- AaiResponse<GetTenantsResponse[]> aaiResponse = new AaiResponse<>(getTenantsResponses, null, 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getTenants(serviceGlobalCustomerId, serviceServiceType);
- Role role = new Role(null, userGlobalCustomerId, userServiceType, userTenantName);
- RoleValidator roleValidator = RoleValidator.by(Collections.singletonList(role));
- AaiResponse<GetTenantsResponse[]> actualTenants = aaiService.getTenants(serviceGlobalCustomerId, serviceServiceType, roleValidator);
-
- assertThat(actualTenants.getT(), arrayWithSize(1));
- assertThat(actualTenants.getT()[0].tenantName, equalTo(serviceTenantName));
- //assertThat(actualTenants.getT()[0].isPermitted, equalTo(expectedIsPermitted));
- }
-}
import org.onap.vid.dal.AsyncInstantiationRepository;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobsBrokerService;
-import org.onap.vid.job.command.*;
+import org.onap.vid.job.command.ALaCarteServiceCommand;
+import org.onap.vid.job.command.CommandUtils;
+import org.onap.vid.job.command.InProgressStatusService;
+import org.onap.vid.job.command.InstanceGroupCommand;
+import org.onap.vid.job.command.InstanceGroupMemberCommand;
+import org.onap.vid.job.command.JobCommandFactory;
+import org.onap.vid.job.command.MacroServiceCommand;
+import org.onap.vid.job.command.MsoRequestBuilder;
+import org.onap.vid.job.command.MsoResultHandlerService;
+import org.onap.vid.job.command.NetworkCommand;
+import org.onap.vid.job.command.VfmoduleCommand;
+import org.onap.vid.job.command.VnfCommand;
+import org.onap.vid.job.command.VolumeGroupCommand;
+import org.onap.vid.job.command.WatchChildrenJobsBL;
import org.onap.vid.job.impl.JobAdapterImpl;
import org.onap.vid.job.impl.JobWorker;
import org.onap.vid.job.impl.JobsBrokerServiceInDatabaseImpl;
+import org.onap.vid.model.ModelUtil;
import org.onap.vid.mso.RestMsoImplementation;
-import org.onap.vid.services.*;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.onap.vid.services.AsyncInstantiationBusinessLogicImpl;
+import org.onap.vid.services.AuditService;
+import org.onap.vid.services.AuditServiceImpl;
+import org.onap.vid.services.CloudOwnerService;
+import org.onap.vid.services.InstantiationTemplatesService;
+import org.onap.vid.services.VersionService;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
return new AsyncInstantiationBusinessLogicImpl(jobAdapter, jobsBrokerService, sessionFactory, aaiClient, featureManager, cloudOwnerService, asyncInstantiationRepository, auditService);
}
+ @Bean
+ public ModelUtil modelUtil() {return new ModelUtil();}
+
+ @Bean
+ public InstantiationTemplatesService instantiationTemplatesService(
+ ModelUtil modelUtil,
+ AsyncInstantiationRepository asyncInstantiationRepository,
+ FeatureManager featureManager
+ ) {
+ return new InstantiationTemplatesService(modelUtil, asyncInstantiationRepository, featureManager);
+ };
+
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
+import static org.mockito.ArgumentMatchers.any;
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.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;
import org.onap.vid.aai.util.AAIRestInterface;
import org.onap.vid.model.VersionByInvariantIdsRequest;
import org.onap.vid.properties.Features;
+import org.onap.vid.roles.AlwaysValidRoleValidator;
import org.onap.vid.roles.RoleProvider;
-import org.onap.vid.roles.RoleValidatorByRoles;
+import org.onap.vid.roles.RoleValidator;
+import org.onap.vid.roles.RoleValidatorBySubscriberAndServiceType;
+import org.onap.vid.roles.RoleValidatorFactory;
import org.onap.vid.services.AaiService;
import org.onap.vid.utils.SystemPropertiesWrapper;
import org.onap.vid.utils.Unchecked;
@Mock
private RoleProvider roleProvider;
@Mock
+ private RoleValidator roleValidator;
+ @Mock
private SystemPropertiesWrapper systemPropertiesWrapper;
@Mock
private FeatureManager featureManager;
public void setUp() {
aaiController = new AaiController(aaiService, aaiRestInterface, roleProvider, systemPropertiesWrapper,
featureManager);
+ when(roleProvider.getUserRolesValidator(any())).thenReturn(roleValidator);
mockMvc = MockMvcBuilders.standaloneSetup(aaiController).build();
}
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),
+ given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidator.class),
eq(isFeatureActive && omitServiceInstances)))
.willReturn(aaiResponse);
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),
+ given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidator.class),
eq(isFeatureActive && omitServiceInstances)))
.willReturn(aaiResponse);
@Test
public void shouldThrowNotAuthorizedException_whenUserIsNotAuthorizedToGetLogs() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(false);
@Test
public void shouldReturnLastAndOneBeforeLogLines_whenLimitIs2() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(true);
@Test
public void shouldReturnEmptyString_whenLogFileIsEmpty() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(true);
@Test
public void shouldReturnEmptyString_whenDebugLogFileIsEmpty() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(true);
import org.jetbrains.annotations.NotNull;
import org.onap.vid.aai.model.Permissions;
+import org.onap.vid.roles.PermissionPropertiesSubscriberAndServiceType;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.roles.RoleValidator;
import org.springframework.mock.web.MockHttpServletRequest;
RoleProvider roleProvider = mock(RoleProvider.class);
RoleValidator roleValidator = mock(RoleValidator.class);
when(roleProvider.getUserRolesValidator(any())).thenReturn(roleValidator);
- when(roleValidator.isServicePermitted(subscriberId, serviceType)).thenReturn(expected);
+ when(roleValidator.isServicePermitted(new PermissionPropertiesSubscriberAndServiceType(subscriberId, serviceType))).thenReturn(expected);
AaiController2 aaiController2 = new AaiController2(null, roleProvider, null, null);
package org.onap.vid.controller;
+import static java.util.stream.Collectors.toMap;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.Matchers.not;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Mockito.times;
+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;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.IntStream;
+import javax.ws.rs.core.MediaType;
import org.apache.log4j.BasicConfigurator;
import org.junit.Assert;
import org.junit.Before;
import org.onap.vid.asdc.AsdcCatalogException;
import org.onap.vid.asdc.beans.SecureServices;
import org.onap.vid.asdc.beans.Service;
-import org.onap.vid.model.*;
+import org.onap.vid.model.CR;
+import org.onap.vid.model.Network;
+import org.onap.vid.model.Node;
import org.onap.vid.model.PombaInstance.PombaRequest;
import org.onap.vid.model.PombaInstance.ServiceInstance;
+import org.onap.vid.model.ServiceModel;
+import org.onap.vid.model.ServiceProxy;
+import org.onap.vid.model.VNF;
+import org.onap.vid.model.VfModule;
+import org.onap.vid.model.VolumeGroup;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.services.AaiService;
+import org.onap.vid.services.InstantiationTemplatesService;
import org.onap.vid.services.PombaService;
import org.onap.vid.services.VidService;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.stream.IntStream;
-
-import static java.util.stream.Collectors.toMap;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.Matchers.not;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.BDDMockito.then;
-import static org.mockito.Mockito.times;
-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;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
@RunWith(MockitoJUnitRunner.class)
public class VidControllerTest {
private RoleProvider roleProvider;
@Mock
private PombaService pombaService;
+ @Mock
+ private InstantiationTemplatesService instantiationTemplatesService;
private VidController vidController;
private MockMvc mockMvc;
@Before
public void setUp() {
- vidController = new VidController(vidService, aaiService, roleProvider, pombaService);
+ vidController = new VidController(vidService, aaiService, roleProvider, pombaService, instantiationTemplatesService);
BasicConfigurator.configure();
mockMvc = MockMvcBuilders.standaloneSetup(vidController).build();
objectMapper = new ObjectMapper();
@Test
public void getServices_shouldReturnService_whenServiceExists() throws Exception {
- List<Service> services = ImmutableList.of(createService(uuid1, 1), createService(uuid2, 2), createService(uuid3, 3));
+ List<Service> services1 = ImmutableList.of(createService(uuid1, 1), createService(uuid2, 2), createService(uuid3, 3));
+ List<Service> services2 = ImmutableList.of(createService(uuid1, 4), createService(uuid2, 5), createService(uuid3, 6));
+
+ given(aaiService.getServicesByDistributionStatus())
+ .willReturn(services1);
- given(aaiService.getServicesByDistributionStatus()).willReturn(services);
+ given(instantiationTemplatesService.setOnEachServiceIsTemplateExists(services1))
+ .willReturn(services2);
SecureServices secureServices = new SecureServices();
- secureServices.setServices(services);
+ secureServices.setServices(services2);
secureServices.setReadOnly(false);
mockMvc.perform(get(REST_MODELS_SERVICES)
convertToMap(networks),
convertToMap(vnfGroups),
null,
- null, false, 1, false,false,null, null, null, null, null, null, null);
+ null, false, 1, false,false,null, null, null, null, null, null, null, null);
}
public static ServiceInstantiation createServiceWith2InstancesInEachLevel(Action action) {
static InstanceGroup createGroup(List<InstanceGroupMember> groupMembers, Action action) {
return new InstanceGroup(mock(ModelInfo.class), null, action.name(), false, null, convertToMap(groupMembers), null, null, null,
- null);
+ null, null);
}
static InstanceGroupMember createMember(Action action) {
- return new InstanceGroupMember(null, action.toString(), null, null, null, null);
+ return new InstanceGroupMember(null, action.toString(), null, null, null, null, null);
}
static Vnf createVnf(List<VfModule> vfModules, Action action) {
vfModulesMap.put("abc",convertToMap(vfModules));
return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, vfModulesMap, null, null, null,
- null);
+ null, null);
}
static Vnf createVnf(Action action) {
return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null,null, null, null, null,
- null);
+ null, null);
}
static VfModule createVfModule(Action action) {
return new VfModule(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null,
- false, false, null, null, null, null, null, null, null);
+ false, false, null, null, null, null, null, null, null, null);
}
static Network createNetwork(Action action) {
return new Network(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, null, null, null,
- null);
+ null, null);
}
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.job.command
+
+import net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.core.AllOf.allOf
+import org.mockito.Answers
+import org.mockito.InjectMocks
+import org.mockito.Mock
+import org.onap.vid.job.JobAdapter
+import org.onap.vid.job.JobsBrokerService
+import org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator
+import org.onap.vid.job.impl.JobSharedData
+import org.onap.vid.model.Action
+import org.onap.vid.mso.RestMsoImplementation
+import org.onap.vid.properties.Features
+import org.onap.vid.services.AsyncInstantiationBusinessLogic
+import org.onap.vid.testUtils.TestUtils
+import org.onap.vid.testUtils.TestUtils.initMockitoMocks
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+import org.togglz.core.manager.FeatureManager
+import org.mockito.Mockito.`when` as _when
+
+class VnfCommandTest {
+
+ @Mock lateinit var asyncInstantiationBL: AsyncInstantiationBusinessLogic
+ @Mock lateinit var restMso: RestMsoImplementation
+ @Mock lateinit var msoRequestBuilder: MsoRequestBuilder
+ @Mock lateinit var msoResultHandlerService: MsoResultHandlerService
+ @Mock lateinit var inProgressStatusService:InProgressStatusService
+ @Mock lateinit var watchChildrenJobsBL: WatchChildrenJobsBL
+ @Mock lateinit var jobsBrokerService: JobsBrokerService
+ @Mock lateinit var jobAdapter: JobAdapter
+ @Mock lateinit var featureManager: FeatureManager
+
+ @Mock lateinit var jobSharedData: JobSharedData
+ @Mock(answer = Answers.RETURNS_MOCKS) lateinit var vnfJobRequest: org.onap.vid.model.serviceInstantiation.Vnf
+
+ @InjectMocks lateinit var vnfCommand: VnfCommand;
+
+ @BeforeMethod
+ fun initMocks() {
+ initMockitoMocks(this)
+ }
+
+ @Test(dataProvider = "trueAndFalse", dataProviderClass = TestUtils::class)
+ fun `childVfModuleWithVnfRegionAndTenant -- given vfmodule -- tenant and region are copied from vnf`(featureToggleOn: Boolean) {
+
+ val vfModule = FakeResourceCreator.createVfModule(Action.Create)
+ .cloneWith("vfmodule-lcp-cloud-region-id", "vfmodule-tenant-id")
+
+ _when(featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(featureToggleOn)
+
+ _when(vnfJobRequest.lcpCloudRegionId).thenReturn("vnf-lcp-cloud-region-id")
+ _when(vnfJobRequest.tenantId).thenReturn("vnf-tenant-id")
+ _when(jobSharedData.request).thenReturn(vnfJobRequest)
+
+ vnfCommand.init(jobSharedData, mapOf())
+
+ val expectedSource = if (featureToggleOn) "vnf" else "vfmodule"
+
+ assertThat(vnfCommand.childVfModuleWithVnfRegionAndTenant(vfModule),
+ allOf(
+ jsonPartEquals("lcpCloudRegionId", "${expectedSource}-lcp-cloud-region-id"),
+ jsonPartEquals("tenantId", "${expectedSource}-tenant-id")
+ )
+ )
+ }
+
+}
import static org.onap.vid.job.impl.JobSchedulerInitializer.WORKERS_TOPICS;
import static org.onap.vid.model.JobAuditStatus.SourceStatus.VID;
import static org.onap.vid.testUtils.TestUtils.readJsonResourceFileAsObject;
+import static org.testng.Assert.assertNull;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import org.onap.vid.services.AsyncInstantiationBaseTest;
import org.onap.vid.services.AsyncInstantiationBusinessLogic;
import org.onap.vid.services.AuditService;
+import org.onap.vid.services.InstantiationTemplatesService;
import org.onap.vid.services.VersionService;
import org.onap.vid.testUtils.TestUtils;
import org.onap.vid.utils.DaoUtils;
@Inject
private CommandUtils commandUtils;
+ @Inject
+ private InstantiationTemplatesService instantiationTemplates;
+
@BeforeClass
void initServicesInfoService() {
createInstanceParamsMaps();
void defineMocks() {
Mockito.reset(restMso);
Mockito.reset(aaiClient);
+ Mockito.reset(commandUtils);
mockAaiClientAnyNameFree();
+
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
+ when(featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(true);
}
@Test
* not looking on audit (yet)
*/
- reset(restMso);
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false); // this makes the test pass without mocking the vfModules
final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
final String VNF_REQUEST_ID = UUID.randomUUID().toString();
String msoVnfStatus = COMPLETE_STR;
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
final String VNF_REQUEST_ID = UUID.randomUUID().toString();
//push alacarte with 1 vnf, verify STATUS pending
UUID uuid = pushALaCarteWithVnf();
singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
- reset(restMso);
/*---------- service -----------*/
NetworkDetails networkDetails1 = new NetworkDetails("LukaDoncic", "1");
NetworkDetails networkDetails2 = new NetworkDetails("KevinDurant", "2");
- reset(restMso);
-
/*---------- service -----------*/
//mock mso to answer 200 of create service instance request, verify STATUS in progress
JobStatus expectedJobStatus,
int getStatusCounter) throws IOException, AsdcCatalogException {
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
- reset(commandUtils);
when(commandUtils.isVfModuleBaseModule("6b528779-44a3-4472-bdff-9cd15ec93450", "f8360508-3f17-4414-a2ed-6bc71161e8db")).thenReturn(true);
when(commandUtils.isVfModuleBaseModule("6b528779-44a3-4472-bdff-9cd15ec93450", "25284168-24bb-4698-8cb4-3f509146eca5")).thenReturn(false);
asyncRequestStatusResponseAsRestObject(IN_PROGRESS_STR),
asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
enableAddCloudOwnerOnMsoRequest();
return readJsonResourceFileAsObject("/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json", ServiceInstantiation.class);
}
+ @Test
+ public void deployService_failIt_retryDeploy_getRetryAsTemplate_makeSureFalsyIsFailedInTemplate() {
+
+ final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
+
+ //push alacarte with 1 vnf, verify STATUS pending
+ UUID uuid = pushALaCarteWithVnf();
+ singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
+
+ //mock mso to answer 200 of create service instance request, verify STATUS in progress
+ when(restMso.restCall(eq(HttpMethod.POST), eq(RequestReferencesContainer.class), any(), endsWith("serviceInstances"), any())).thenReturn(
+ createResponse(200, SERVICE_INSTANCE_ID, SERVICE_REQUEST_ID));
+
+ //mock mso to answer FAILED for service instance create
+ final RestObject<AsyncRequestStatus> failedResponse = asyncRequestStatusResponseAsRestObject(FAILED_STR);
+ final String failureDescription = "Some deep failure";
+ failedResponse.get().request.requestStatus.setStatusMessage(failureDescription);
+ when(restMso.GetForObject(endsWith(SERVICE_REQUEST_ID), eq(AsyncRequestStatus.class))).
+ thenReturn(failedResponse);
+
+ //Wait till job failed
+ processJobsCountTimesAndAssertStatus(uuid, 3, FAILED);
+
+ //make sure retry request jas isFailed = true, and status message is with failureDescription
+ ServiceInstantiation retryRequest = asyncInstantiationBL.getBulkForRetry(uuid);
+ assertTrue(retryRequest.getIsFailed());
+ assertEquals(failureDescription, retryRequest.getStatusMessage());
+
+ //deploy retry job and it's template
+ UUID retryUuid = asyncInstantiationBL.pushBulkJob(retryRequest, USER_ID).get(0);
+ ServiceInstantiation templateOfRetry = instantiationTemplates.getJobRequestAsTemplate(retryUuid);
+
+ //make sure the template request has isFailed = false, and no status message
+ assertFalse(templateOfRetry.getIsFailed());
+ assertNull(templateOfRetry.getStatusMessage());
+ }
+
}
package org.onap.vid.model;
-import org.junit.Test;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanEqualsFor;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanHashCodeFor;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonNodeAbsent;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
+import static org.apache.commons.lang3.ArrayUtils.toArray;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
public class ServiceInstanceSearchResultTest {
- private ServiceInstanceSearchResult createTestSubject() {
- return new ServiceInstanceSearchResult();
- }
-
- @Test
- public void testGetServiceInstanceId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getServiceInstanceId();
- }
-
- @Test
- public void testSetServiceInstanceId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String serviceInstanceId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setServiceInstanceId(serviceInstanceId);
- }
-
- @Test
- public void testGetGlobalCustomerId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getGlobalCustomerId();
- }
-
- @Test
- public void testSetGlobalCustomerId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String globalCustomerId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setGlobalCustomerId(globalCustomerId);
- }
-
- @Test
- public void testGetServiceType() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getServiceType();
- }
-
- @Test
- public void testSetServiceType() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String serviceType = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setServiceType(serviceType);
- }
-
- @Test
- public void testGetServiceInstanceName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getServiceInstanceName();
- }
-
- @Test
- public void testSetServiceInstanceName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String serviceInstanceName = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setServiceInstanceName(serviceInstanceName);
- }
-
- @Test
- public void testGetSubscriberName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getSubscriberName();
- }
-
- @Test
- public void testSetSubscriberName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String subscriberName = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setSubscriberName(subscriberName);
- }
-
@Test
- public void testGetAaiModelInvariantId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getAaiModelInvariantId();
- }
-
- @Test
- public void testSetAaiModelInvariantId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String aaiModelInvariantId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setAaiModelInvariantId(aaiModelInvariantId);
- }
-
- @Test
- public void testGetAaiModelVersionId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getAaiModelVersionId();
+ public void shouldHaveValidGettersAndSetters() {
+ assertThat(ServiceInstanceSearchResult.class, hasValidGettersAndSetters());
}
@Test
- public void testSetAaiModelVersionId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String aaiModelVersionId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setAaiModelVersionId(aaiModelVersionId);
- }
-
- @Test
- public void testGetIsPermitted() throws Exception {
- ServiceInstanceSearchResult testSubject;
- boolean result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getIsPermitted();
+ public void shouldHaveValidConstructor() {
+ assertThat(ServiceInstanceSearchResult.class, hasValidBeanConstructor());
}
@Test
- public void testSetIsPermitted() throws Exception {
- ServiceInstanceSearchResult testSubject;
- boolean isPermitted = false;
+ public void shouldHaveValidEqualsAndHashCode() {
+ String[] propertiesToEqualBy = toArray("serviceInstanceId");
- // default test
- testSubject = createTestSubject();
- testSubject.setIsPermitted(isPermitted);
+ assertThat(ServiceInstanceSearchResult.class, allOf(
+ hasValidBeanHashCodeFor(propertiesToEqualBy),
+ hasValidBeanEqualsFor(propertiesToEqualBy))
+ );
}
@Test
- public void testEquals() throws Exception {
- ServiceInstanceSearchResult testSubject;
- Object other = null;
- boolean result;
+ public void subscriberId_shouldBeSerializedAsGlobalCustomerId() {
+ ServiceInstanceSearchResult underTest = new ServiceInstanceSearchResult();
+ underTest.setSubscriberId("example");
- // default test
- testSubject = createTestSubject();
- result = testSubject.equals(other);
+ assertThat(underTest, jsonPartEquals("globalCustomerId", "example"));
+ assertThat(underTest, jsonNodeAbsent("subscriberId"));
}
}
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.InvocationTargetException;
+import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.onap.vid.model.VidNotions;
import org.onap.vid.model.VidNotions.InstantiationUI;
import org.onap.vid.model.VidNotions.ModelCategory;
import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
import org.testng.annotations.Test;
public class InstantiationModelSerializationTest {
new VidNotions(InstantiationUI.ANY_ALACARTE_WHICH_NOT_EXCLUDED,
ModelCategory.INFRASTRUCTURE_VPN,
InstantiationUI.INFRASTRUCTURE_VPN,
- InstantiationType.Macro)
+ InstantiationType.Macro),
+ "originalName"
);
verifySerializationAndDeserialization(serviceInstantiation);
"trackById",
true,
"statusMessage",
- 5);
+ 5,
+ "originalName");
verifySerializationAndDeserialization(vnf);
}
@Test
public void serializeAndDeserializeVfModule() throws Exception {
- ImmutableMap<String, String> supplementaryParams = ImmutableMap.of(
- "uno", "1",
- "dos", "2",
- "tres", "3"
+ List<UserParamNameAndValue> supplementaryParams = ImmutableList.of(
+ new UserParamNameAndValue("uno", "1"),
+ new UserParamNameAndValue("dos", "2"),
+ new UserParamNameAndValue("tres", "3")
);
VfModule vfModule = new VfModule(
"statusMessage",
true,
true,
- 1);
+ 1,
+ "originalName");
verifySerializationAndDeserialization(vfModule);
}
VfModule vfModule = new VfModule(newModelInfo(), null, null, null,
null, null, null, null, null, false,
/* HERE ====> */ USE_PRELOAD,
- null, null, null, null, null, null, null);
+ null, null, null, null, null, null, null, null);
assertThat(vfModule, jsonPartEquals("sdncPreLoad", USE_PRELOAD));
assertThat(vfModule, jsonNodeAbsent("usePreload"));
/* HERE ====> */ VOLUME_GROUP_INSTANCE_NAME,
null, null, null, null, null, null,
false, null, null, null, null, null,
- null, null, null);
+ null, null, null, null);
assertThat(vfModule, jsonPartEquals("volumeGroupName", VOLUME_GROUP_INSTANCE_NAME));
assertThat(vfModule, jsonNodeAbsent("volumeGroupInstanceName"));
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.model.serviceInstantiation;
+
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.hamcrest.core.AllOf.allOf;
+import static org.onap.vid.testUtils.TestUtils.setStringsInStringProperties;
+
+import org.onap.vid.mso.model.ModelInfo;
+import org.testng.annotations.Test;
+
+public class VfModuleTest {
+
+ @Test
+ public void cloneWithLcpCloudRegionIdAndTenantId() {
+ String targetLcpCloudRegionId = "dictated lcpCloudRegionId";
+ String targetTenantId = "dictated tenantId";
+
+ VfModule originVfModule = createVfModule();
+
+ assertThat(originVfModule.cloneWith(targetLcpCloudRegionId, targetTenantId), allOf(
+ hasProperty("lcpCloudRegionId", equalTo(targetLcpCloudRegionId)),
+ hasProperty("tenantId", equalTo(targetTenantId)),
+ jsonEquals(originVfModule).whenIgnoringPaths("lcpCloudRegionId", "tenantId")
+ ));
+
+ // verify vfModule did not mutate
+ assertThat(originVfModule, jsonEquals(createVfModule()));
+ }
+
+ private VfModule createVfModule() {
+ VfModule vfModule = new VfModule(
+ setStringsInStringProperties(new ModelInfo()),
+ null, null, null, null, null,
+ null, null, null, true, true,
+ null, null, true, null, true,
+ true, null, null);
+
+ return setStringsInStringProperties(vfModule);
+ }
+}
\ No newline at end of file
import io.joshworks.restclient.http.HttpResponse;
import org.onap.vid.testUtils.TestUtils;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class MsoUtilTest {
assertThat(result.getStatus()).isEqualTo(SC_OK);
}
+ @DataProvider
+ public static Object[][] formatExceptionAdditionalInfo() {
+ return new Object[][]{
+ {"message", "Http Code:400, message"},
+
+ {null, "Http Code:400"},
+
+ {"{\"requestError\":{\"serviceException\":{\"messageId\":\"SVC0002\",\"text\":\"message\"}}}",
+ "Http Code:400, \"messageId\":\"SVC0002\",\"text\":\"message\""},
+
+ {"{\"validJson\": \"Error: message\"}", "Http Code:400, {\"validJson\": \"Error: message\"}"},
+
+ {"{\"serviceException\":{\"messageId\":\"SVC0002\",\"text\":\"Error: message\"}}",
+ "Http Code:400, \"messageId\":\"SVC0002\",\"text\":\"Error: message\""},
+ };
+ }
+
+ @Test(dataProvider = "formatExceptionAdditionalInfo")
+ public void formatExceptionAdditionalInfo_payloadWithError400_doNotReturnNull(String payload, String expected) {
+ assertThat(MsoUtil.formatExceptionAdditionalInfo(400, payload))
+ .isEqualTo(expected);
+ }
}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.mso.model;
+
+import static java.util.Collections.emptyList;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
+
+public class RequestParametersVfModuleTest {
+
+ @Test
+ public void RequestParametersVfModuleOrVolumeGroupInstantiation_whenUsePreloadIsNull_thenLiteralFalseIsSerialized() {
+ Boolean usePreload = null;
+ assertThat(
+ new RequestParametersVfModuleOrVolumeGroupInstantiation(emptyList(), usePreload, ""),
+ jsonPartEquals("usePreload", false)
+ );
+ }
+
+ @Test
+ public void RequestParametersVfModuleUpgrade_whenUsePreloadIsNull_thenLiteralFalseIsSerialized() {
+ Boolean usePreload = null;
+ assertThat(
+ new RequestParametersVfModuleUpgrade(emptyList(), usePreload, "", false, false),
+ jsonPartEquals("usePreload", false)
+ );
+ }
+
+}
--- /dev/null
+package org.onap.vid.properties
+
+import org.hamcrest.CoreMatchers.*
+import org.hamcrest.MatcherAssert.assertThat
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.InjectMocks
+import org.mockito.Mock
+import org.mockito.Mockito.*
+import org.onap.vid.testUtils.TestUtils
+import org.springframework.web.context.request.RequestContextHolder
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+import org.togglz.core.manager.FeatureManager
+import javax.servlet.ServletContext
+import javax.servlet.http.Cookie
+import javax.servlet.http.HttpServletRequest
+import org.hamcrest.CoreMatchers.`is` as _is
+import org.mockito.Mockito.`when` as _when
+
+class FeatureSetsManagerTest {
+ @Mock
+ lateinit var defaultFeatureManager: FeatureManager
+ @Mock
+ lateinit var servletContext: ServletContext
+ @Mock
+ lateinit var alternativeFeatureSetNameProvider: AlternativeFeatureSetNameProvider
+ @InjectMocks
+ lateinit var featureSetsManager: FeatureSetsManager
+
+ private val alternativeFeatureSetNameFromCookie = AlternativeFeatureSetNameFromCookie()
+
+ @BeforeMethod
+ fun setUp() {
+ TestUtils.initMockitoMocks(this)
+ }
+
+ @Test
+ fun `isActive - without alternative features set name - delegates to default and no file loaded`() {
+ _when(defaultFeatureManager.isActive(Features.FLAG_1810_AAI_LOCAL_CACHE)).thenReturn(true)
+ _when(alternativeFeatureSetNameProvider.alternativeFeatureSetName).thenReturn(null)
+
+ assertThat(featureSetsManager.isActive(Features.FLAG_1810_AAI_LOCAL_CACHE), _is(true))
+
+ verifyZeroInteractions(servletContext) // implies no other file loaded
+ verify(defaultFeatureManager, times(1)).isActive(Features.FLAG_1810_AAI_LOCAL_CACHE)
+ }
+
+ @Test
+ fun `isActive - with alternative features set - brings flags from alternative`() {
+ _when(servletContext.getRealPath(anyString())).thenReturn(this.javaClass.getResource("/").path)
+ _when(alternativeFeatureSetNameProvider.alternativeFeatureSetName).thenReturn("example.features.properties")
+
+ assertThat(featureSetsManager.isActive(Features.FLAG_1810_AAI_LOCAL_CACHE), _is(true))
+ assertThat(featureSetsManager.isActive(Features.FLAG_1902_NEW_VIEW_EDIT), _is(false))
+ verifyZeroInteractions(defaultFeatureManager)
+ }
+
+ @Test
+ fun `isActive - with non-existing alternative features set - fallback is to all flags off`() {
+ _when(servletContext.getRealPath(anyString())).thenReturn(this.javaClass.getResource("/").path)
+ _when(alternativeFeatureSetNameProvider.alternativeFeatureSetName).thenReturn("non-existing")
+
+ assertThat(featureSetsManager, not(nullValue()))
+ assertThat(
+ featureSetsManager.features.map { featureSetsManager.isActive(it) },
+ not(hasItem(true))
+ )
+ }
+
+ @Test
+ fun `valueFromCookie - given no request - return null`() {
+ assertThat(alternativeFeatureSetNameFromCookie.valueFromCookie(null), _is(nullValue()))
+ }
+
+ @Test
+ fun `valueFromCookie - given request - return the correct cookie value`() {
+ val servletRequestMock = mock(HttpServletRequest::class.java)
+ _when(servletRequestMock.cookies).thenReturn(arrayOf(Cookie("features.set", "value")))
+
+ assertThat(alternativeFeatureSetNameFromCookie.valueFromCookie(servletRequestMock), _is("value"))
+ }
+
+ @Test
+ fun `valueFromCookie - given request without cookies - return null`() {
+ val servletRequestMock = mock(HttpServletRequest::class.java)
+ _when(servletRequestMock.cookies).thenReturn(emptyArray())
+
+ assertThat(alternativeFeatureSetNameFromCookie.valueFromCookie(servletRequestMock), _is(nullValue()))
+ }
+
+ @Test
+ fun `currentHttpRequest - when no current request - return null`() {
+ assertPrecondition()
+ assertThat(alternativeFeatureSetNameFromCookie.currentHttpRequest(), _is(nullValue()))
+ }
+
+ private fun assertPrecondition() {
+ assertThat("precondition for test not met: static RequestContextHolder.getRequestAttributes should be null",
+ RequestContextHolder.getRequestAttributes(), _is(nullValue()))
+ }
+}
@Test
public void testIsServicePermitted() {
- assertTrue(new AlwaysValidRoleValidator().isServicePermitted("any", "any"));
+ WithPermissionProperties emptyPermissionProperties = new WithPermissionProperties() {};
+ assertTrue(new AlwaysValidRoleValidator().isServicePermitted(emptyPermissionProperties));
}
@Test
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
public class RoleProviderTest {
private static final String SAMPLE_SUBSCRIBER = "sampleSubscriber";
- private static final String SAMPLE_CUSTOMER_ID = "sampleCustomerId";
+ private static final String SAMPLE_SUBSCRIBER_ID = "subscriberId";
private static final String SERVICE_TYPE_LOGS = "LOGS";
private static final String TENANT_PERMITTED = "PERMITTED";
private static final String SAMPLE_SERVICE = "sampleService";
@Mock
private AaiResponse<SubscriberList> subscriberListResponse;
+ @Mock
+ private RoleValidatorFactory roleValidatorFactory;
+
private RoleProvider roleProvider;
@BeforeMethod
public void setUp() {
initMocks(this);
- roleProvider = new RoleProvider(aaiService, httpServletRequest -> 5, httpServletRequest -> createRoles());
+ roleProvider = new RoleProvider(aaiService, roleValidatorFactory, httpServletRequest -> 5, httpServletRequest -> createRoles());
}
@Test
Role role = roleProvider.createRoleFromStringArr(roleParts, SAMPLE_ROLE_PREFIX);
assertThat(role.getEcompRole()).isEqualTo(EcompRole.READ);
- assertThat(role.getSubscribeName()).isEqualTo(SAMPLE_CUSTOMER_ID);
+ assertThat(role.getSubscriberId()).isEqualTo(SAMPLE_SUBSCRIBER_ID);
assertThat(role.getTenant()).isEqualTo(SAMPLE_TENANT);
assertThat(role.getServiceType()).isEqualTo(SAMPLE_SERVICE);
}
Role role = roleProvider.createRoleFromStringArr(roleParts, SAMPLE_ROLE_PREFIX);
assertThat(role.getEcompRole()).isEqualTo(EcompRole.READ);
- assertThat(role.getSubscribeName()).isEqualTo(SAMPLE_CUSTOMER_ID);
+ assertThat(role.getSubscriberId()).isEqualTo(SAMPLE_SUBSCRIBER_ID);
assertThat(role.getServiceType()).isEqualTo(SAMPLE_SERVICE);
assertThat(role.getTenant()).isNullOrEmpty();
}
@Test
public void shouldProperlyRetrieveUserRolesWhenPermissionIsDifferentThanRead() {
- Role expectedRole = new Role(EcompRole.READ, SAMPLE_CUSTOMER_ID, SAMPLE_SERVICE, SAMPLE_TENANT);
+ Role expectedRole = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER_ID, SAMPLE_SERVICE, SAMPLE_TENANT, owningEntityId());
setSubscribers();
List<Role> userRoles = roleProvider.getUserRoles(request);
Role actualRole = userRoles.get(0);
assertThat(actualRole.getTenant()).isEqualTo(expectedRole.getTenant());
- assertThat(actualRole.getSubscribeName()).isEqualTo(expectedRole.getSubscribeName());
+ assertThat(actualRole.getSubscriberId()).isEqualTo(expectedRole.getSubscriberId());
assertThat(actualRole.getServiceType()).isEqualTo(expectedRole.getServiceType());
}
@Test
public void shouldReturnNotReadOnlyPermissionWhenRolesArePresent() {
- assertThat(roleProvider.userPermissionIsReadOnly(Lists.list(new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT)))).isFalse();
+ assertThat(roleProvider.userPermissionIsReadOnly(Lists.list(new Role(
+ EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT, owningEntityId())))).isFalse();
}
@Test
public void userShouldHavePermissionToReadLogsWhenServiceAndTenantAreCorrect() {
- Role withoutPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT);
- Role withPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SERVICE_TYPE_LOGS, TENANT_PERMITTED);
+ Role withoutPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT, owningEntityId());
+ Role withPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SERVICE_TYPE_LOGS, TENANT_PERMITTED, owningEntityId());
assertThat(roleProvider.userPermissionIsReadLogs(Lists.list(withoutPermission, withPermission))).isTrue();
}
+ @Test
+ public void getUserRolesValidator_shouldReturnValidatorFromFactory() {
+ RoleValidator expectedRoleValidator = new AlwaysValidRoleValidator();
+ when(roleValidatorFactory.by(any())).thenReturn(expectedRoleValidator);
+
+ RoleValidator result = roleProvider.getUserRolesValidator(request);
+
+ assertThat(result).isEqualTo(expectedRoleValidator);
+ }
+
+ private String owningEntityId() {
+ // while translateOwningEntityNameToOwningEntityId does nothing, no translation happens.
+ // this will be changed later.
+ return SAMPLE_SUBSCRIBER;
+ }
+
private void setSubscribers() {
Subscriber subscriber = new Subscriber();
subscriber.subscriberName = SAMPLE_SUBSCRIBER;
- subscriber.globalCustomerId = SAMPLE_CUSTOMER_ID;
+ subscriber.globalCustomerId = SAMPLE_SUBSCRIBER_ID;
SubscriberList subscriberList = new SubscriberList(Lists.list(subscriber));
when(aaiService.getFullSubscriberList()).thenReturn(subscriberListResponse);
when(subscriberListResponse.getT()).thenReturn(subscriberList);
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.withSettings;
+import static org.testng.Assert.assertFalse;
+
+import com.google.common.collect.ImmutableList;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class RoleValidatorByOwningEntityTest {
+
+ private static final String OWNING_ENTITY_ID = "owningEntityId";
+ private static final String SUBSCRIBER_NAME = "subscriber_name";
+ private static final String NOT_MATCHING_OWNING_ENTITY_ID = "notMatchingOwningEntityId";
+
+ private static final String SERVICE_TYPE = "serviceType";
+ private static final String GLOBAL_CUSTOMER_ID = "globalCustomerId";
+ private static final String TENANT_NAME = "tenantName";
+
+
+ private RoleValidatorByOwningEntity roleValidatorByOwningEntity;
+
+ @BeforeMethod
+ public void setup() {
+ final Role SAMPLE_ROLE = new Role(EcompRole.READ, "", "", "", OWNING_ENTITY_ID);
+ roleValidatorByOwningEntity = new RoleValidatorByOwningEntity(ImmutableList.of(SAMPLE_ROLE));
+ }
+
+ @Test
+ public void testIsSubscriberPermitted() {
+ assertFalse(roleValidatorByOwningEntity.isSubscriberPermitted(SUBSCRIBER_NAME));
+ }
+
+ @Test
+ public void isServicePermitted_owningEntityMatch_returnTrue() {
+ PermissionPropertiesOwningEntity permittedOwningEntity =
+ new PermissionPropertiesOwningEntity(OWNING_ENTITY_ID);
+
+ assertThat(roleValidatorByOwningEntity.isServicePermitted(permittedOwningEntity), is(true));
+ }
+
+ @DataProvider
+ public static Object[][] nonMatchingPermissionProperties() {
+ return new Object[][]{
+ {new PermissionPropertiesOwningEntity(NOT_MATCHING_OWNING_ENTITY_ID)},
+ {new PermissionPropertiesOwningEntity("")},
+ {new WithPermissionProperties() {}},
+ {mock(PermissionPropertiesOwningEntity.class,
+ withSettings().name("PermissionPropertiesOwningEntity with null owningEntityId"))},
+ {new PermissionPropertiesSubscriberAndServiceType(OWNING_ENTITY_ID, OWNING_ENTITY_ID)},
+ };
+ }
+
+ @Test(dataProvider = "nonMatchingPermissionProperties")
+ public void isServicePermitted_nonMatchingPermissionProperties_returnFalse(WithPermissionProperties permissionProperties) {
+ assertThat(permissionProperties.toString(), roleValidatorByOwningEntity.isServicePermitted(
+ permissionProperties
+ ), is(false));
+ }
+
+ @Test
+ public void testIsTenantPermitted() {
+ assertFalse(roleValidatorByOwningEntity.isTenantPermitted(GLOBAL_CUSTOMER_ID, SERVICE_TYPE, TENANT_NAME));
+ }
+
+}
+++ /dev/null
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.roles;
-
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.util.List;
-import java.util.Map;
-import org.onap.vid.mso.rest.RequestDetails;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class RoleValidatorByRolesTest {
-
- private static final String SAMPLE_SUBSCRIBER = "sampleSubscriber";
- private static final String NOT_MATCHING_SUBSCRIBER = "notMatchingSubscriber";
- private static final String SAMPLE_SERVICE_TYPE = "sampleServiceType";
- private static final String NOT_MATCHING_TENANT = "notMatchingTenant";
- private static final String SAMPLE_TENANT = "sampleTenant";
-
- private static final Role SAMPLE_ROLE = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT);
-
- private List<Role> roles = ImmutableList.of(SAMPLE_ROLE);
- private Map<String, Object> subscriberInfo = ImmutableMap.of("globalSubscriberId", SAMPLE_SUBSCRIBER);
- private Map<String, Object> requestParameters = ImmutableMap.of("subscriptionServiceType", SAMPLE_SERVICE_TYPE);
- private Map<String, Object> requestDetailsProperties = ImmutableMap.of("subscriberInfo", subscriberInfo, "requestParameters", requestParameters);
- private RequestDetails requestDetails;
- private RoleValidatorByRoles roleValidator;
-
- @BeforeMethod
- public void setUp() {
- roleValidator = new RoleValidatorByRoles(roles);
- requestDetails = new RequestDetails();
- }
-
- @Test
- public void shouldPermitSubscriberWhenNameMatchesAndRolesAreEnabled() {
- assertThat(roleValidator.isSubscriberPermitted(SAMPLE_SUBSCRIBER)).isTrue();
- }
-
- @Test
- public void shouldNotPermitSubscriberWhenNameNotMatches() {
- assertThat(roleValidator.isSubscriberPermitted(NOT_MATCHING_SUBSCRIBER)).isFalse();
- }
-
- @Test
- public void shouldPermitServiceWhenNamesMatches() {
- assertThat(roleValidator.isServicePermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE)).isTrue();
- }
-
-
- @Test
- public void shouldNotPermitServiceWhenSubscriberNameNotMatches() {
- assertThat(roleValidator.isServicePermitted(NOT_MATCHING_SUBSCRIBER, SAMPLE_SERVICE_TYPE)).isFalse();
- }
-
- @Test
- public void shouldNotPermitServiceWhenServiceTypeNotMatches() {
- assertThat(roleValidator.isServicePermitted(SAMPLE_SUBSCRIBER, NOT_MATCHING_SUBSCRIBER)).isFalse();
- }
-
- @Test
- public void shouldPermitTenantWhenNameMatches() {
- assertThat(roleValidator.isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT)).isTrue();
- }
-
-
- @Test
- public void shouldNotPermitTenantWhenNameNotMatches() {
- assertThat(roleValidator.isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, NOT_MATCHING_TENANT)).isFalse();
- }
-
- @Test
- public void shouldValidateProperlySORequest() {
- requestDetails.setAdditionalProperty("requestDetails", requestDetailsProperties);
-
- assertThat(roleValidator.isMsoRequestValid(requestDetails)).isTrue();
- }
-
- @Test
- public void shouldValidateUnknownSORequest() {
- assertThat(roleValidator.isMsoRequestValid(new RequestDetails())).isTrue();
- }
-
- @Test
- public void shouldRejectSORequestWhenSubscriberNotMatches() {
- Map<String, Object> subscriberInfo = ImmutableMap.of("globalSubscriberId", "sample");
- Map<String, Object> requestDetailsProperties = ImmutableMap.of("subscriberInfo", subscriberInfo, "requestParameters", requestParameters);
- requestDetails.setAdditionalProperty("requestDetails", requestDetailsProperties);
-
- assertThat(roleValidator.isMsoRequestValid(requestDetails)).isFalse();
- }
-}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class RoleValidatorBySubscriberAndServiceTypeTest {
+
+ private static final String SAMPLE_SUBSCRIBER = "sampleSubscriber";
+ private static final String NOT_MATCHING_SUBSCRIBER = "notMatchingSubscriber";
+ private static final String SAMPLE_SERVICE_TYPE = "sampleServiceType";
+ private static final String NOT_MATCHING_TENANT = "notMatchingTenant";
+ private static final String SAMPLE_TENANT = "sampleTenant";
+ private static final String SOME_OWNING_ENTITY_ID = "someOwningEntityId";
+
+ private static final Role SAMPLE_ROLE = new Role(
+ EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT, SOME_OWNING_ENTITY_ID);
+
+ private List<Role> roles = ImmutableList.of(SAMPLE_ROLE);
+ private RoleValidatorBySubscriberAndServiceType roleValidatorBySubscriberAndServiceType;
+
+ @BeforeMethod
+ public void setUp() {
+ roleValidatorBySubscriberAndServiceType = new RoleValidatorBySubscriberAndServiceType(roles);
+ }
+
+ @Test
+ public void shouldPermitSubscriberWhenNameMatchesAndRolesAreEnabled() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isSubscriberPermitted(SAMPLE_SUBSCRIBER)).isTrue();
+ }
+
+ @Test
+ public void shouldNotPermitSubscriberWhenNameNotMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isSubscriberPermitted(NOT_MATCHING_SUBSCRIBER)).isFalse();
+ }
+
+ @Test
+ public void shouldPermitServiceWhenNamesMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE))).isTrue();
+ }
+
+ @Test
+ public void isServicePermitted_serviceWithAllPermissionProperties_isPermitted() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new AllPermissionProperties(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SOME_OWNING_ENTITY_ID))).isTrue();
+ }
+
+ @Test
+ public void shouldNotPermitServiceWhenSubscriberNameNotMatches() {
+ assertThat(
+ roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(NOT_MATCHING_SUBSCRIBER, SAMPLE_SERVICE_TYPE))).isFalse();
+ }
+
+ @Test
+ public void shouldNotPermitServiceWhenServiceTypeNotMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(SAMPLE_SUBSCRIBER, NOT_MATCHING_SUBSCRIBER))).isFalse();
+ }
+
+ @Test
+ public void isServicePermitted_owningEntityPermissionProperties_isNotPermitted() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesOwningEntity(SAMPLE_SUBSCRIBER))).isFalse();
+ }
+
+ @Test
+ public void shouldPermitTenantWhenNameMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType
+ .isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT)).isTrue();
+ }
+
+ @Test
+ public void shouldPermitTenantWhenNameMatchesCaseInsensitive() {
+ assertThat(roleValidatorBySubscriberAndServiceType
+ .isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT.toUpperCase())).isTrue();
+ }
+
+
+ @Test
+ public void shouldNotPermitTenantWhenNameNotMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType
+ .isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, NOT_MATCHING_TENANT)).isFalse();
+ }
+
+}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+import static java.util.Collections.emptyList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.properties.Features;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.togglz.core.manager.FeatureManager;
+
+public class RoleValidatorFactoryTest {
+
+ @InjectMocks
+ private RoleValidatorFactory roleValidatorFactory;
+
+ @Mock
+ private FeatureManager featureManager;
+
+ @BeforeClass
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @AfterMethod
+ public void reset() {
+ Mockito.reset(featureManager);
+ }
+
+ @Test (dataProvider = "presetRoleValidatorClass")
+ public void returnRoleValidatorByGivenClass_And_RoleManagementActivated_And_FeatureFlag(Class expectedClass,boolean isDisabledRoles, boolean flagActive ) {
+
+ when(featureManager.isActive(Features.FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY)).thenReturn(flagActive);
+ RoleValidator roleValidator = roleValidatorFactory.by(emptyList(), isDisabledRoles);
+ assertThat(roleValidator, instanceOf(expectedClass));
+ }
+
+ @DataProvider
+ public static Object[][] presetRoleValidatorClass() {
+ return new Object[][] {
+ {RoleValidatorsComposer.class, false, true},
+ {AlwaysValidRoleValidator.class, true, true},
+ {RoleValidatorBySubscriberAndServiceType.class, false, false},
+ {AlwaysValidRoleValidator.class, true, false}
+ };
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+import static java.util.stream.Collectors.toList;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.withSettings;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class RoleValidatorsComposerTest {
+
+ private RoleValidator alwaysTrueRoles;
+ private RoleValidator alwaysFalseRoles;
+
+ @DataProvider
+ public static Object[][] allInterfaceFunctions() {
+ return Stream.<Function<RoleValidator, Boolean>>of(
+ (RoleValidator o) -> o.isSubscriberPermitted("subscriberId"),
+ (RoleValidator o) -> o.isServicePermitted(new WithPermissionProperties() {}),
+ (RoleValidator o) -> o.isTenantPermitted("subscriberId", "serviceType", "tenantName")
+ ).map(it -> new Object[]{it}).collect(toList()).toArray(new Object[][]{});
+ }
+
+ @BeforeMethod
+ public void setUp() {
+ alwaysTrueRoles = mock(RoleValidator.class, withSettings().defaultAnswer(o -> true));
+ alwaysFalseRoles = mock(RoleValidator.class);
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void emptyComposite_returnsFalse(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer();
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(false)
+ );
+
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void falseAndTrueComposite_returnsTrue(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest =
+ new RoleValidatorsComposer(alwaysFalseRoles, alwaysFalseRoles, alwaysTrueRoles);
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(true)
+ );
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void trueAndFalseComposite_returnsTrueAndShortCircuits(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer(alwaysTrueRoles, alwaysFalseRoles);
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(true)
+ );
+
+ verifyZeroInteractions(alwaysFalseRoles);
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void falseAndFalseComposite_returnsFalse(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer(alwaysFalseRoles, alwaysFalseRoles);
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(false)
+ );
+ }
+
+ @Test
+ public void secondaryConstructor_givenSetIfValidators_returnsTrue() {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer(
+ ImmutableSet.of(alwaysTrueRoles)
+ );
+
+ assertThat(underTest.isSubscriberPermitted("anything"), is(true));
+ }
+
+}
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
private ExecutorService executorService;
private Logging logging = new Logging();
+ private static final Logger logger = LogManager.getLogger(AAITreeNodeBuilderTest.class);
private static final ObjectMapper mapper = new ObjectMapper();
private void buildNodeAndAssert(JsonNode inputNode, AAITreeNode expectedNode, NodeType nodeType){
ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
when(aaiClientMock.typedAaiRest(Unchecked.toURI("anyUrl"), JsonNode.class, null, HttpMethod.GET, false)).thenReturn(inputNode);
- AAITreeNode actualNode = aaiTreeNodeBuilder.buildNode(
+ AAITreeNode actualNode;
+ try {
+ actualNode = aaiTreeNodeBuilder.buildNode(
nodeType,
"anyUrl",
null,
nodesAccumulator,
executorService,
AAI_TREE_PATHS.getSubTree(new AAIServiceTree.AaiRelationship(nodeType))
- ).get(0);
+ ).get(0);
+ } catch (Throwable e) {
+ //print stack traces for more information in case of failure
+ System.out.println("Failed to build node by aaiTreeNodeBuilder");
+ ExceptionUtils.getThrowableList(e)
+ .stream()
+ .peek(it ->System.err.println(it.getLocalizedMessage()))
+ .forEach(Throwable::printStackTrace);
+ throw e;
+ }
assertThat(actualNode, jsonEquals(expectedNode).when(IGNORING_ARRAY_ORDER, IGNORING_EXTRA_FIELDS).whenIgnoringPaths("relationshipList","children[0].relationshipList"));
}
AaiResponse<Services> aaiResponseServices = new AaiResponse<>(services, null, HttpStatus.SC_OK);
when(aaiClient.getSubscriberData(SUBSCRIBER_ID, false)).thenReturn(aaiResponseServices);
- when(roleValidator.isServicePermitted(eq(GLOBAL_CUSTOMER_ID), anyString())).thenReturn(Boolean.TRUE);
+ when(roleValidator.isServicePermitted(any())).thenReturn(Boolean.TRUE);
AaiResponse actualResponse = aaiService.getSubscriberData(SUBSCRIBER_ID, roleValidator, false);
List<ServiceSubscription> actualServiceSubscriptions = ((AaiResponse<Services>) actualResponse)
package org.onap.vid.services;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
+import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.jetbrains.annotations.NotNull;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.onap.vid.aai.AaiClientInterface;
import org.onap.vid.aai.AaiResponse;
+import org.onap.vid.aai.ServiceInstance;
import org.onap.vid.aai.model.AaiGetPnfResponse;
import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.onap.vid.aai.model.LogicalLinkResponse;
+import org.onap.vid.aai.model.OwningEntityResponse;
+import org.onap.vid.aai.model.ProjectResponse;
import org.onap.vid.aai.model.Relationship;
import org.onap.vid.aai.model.RelationshipData;
import org.onap.vid.aai.model.RelationshipList;
import org.onap.vid.aai.model.ServiceRelationships;
+import org.onap.vid.model.ServiceInstanceSearchResult;
import org.onap.vid.model.aaiTree.AAITreeNode;
-import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleValidator;
+import org.onap.vid.roles.RoleValidatorFactory;
+import org.onap.vid.roles.WithPermissionProperties;
+import org.onap.vid.testUtils.TestUtils;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@Mock
private AaiClientInterface aaiClientInterface;
+ @Mock
+ private RoleValidatorFactory roleValidatorFactory;
+
@BeforeMethod
public void initMocks(){
MockitoAnnotations.initMocks(this);
@Test
public void testGetSpecificPnf(){
- Pnf pnf = new Pnf("11111", null, null, null, null, null, null);
+ Pnf pnf = Pnf.builder().withPnfId("11111").build();
AaiResponse<Pnf> aaiResponse = new AaiResponse<>(pnf, "aaaa", 200);
Mockito.doReturn(aaiResponse).when(aaiClientInterface).getSpecificPnf(Mockito.anyString());
AaiResponse<Pnf> specificPnf = aaiService.getSpecificPnf("1345667");
public static Object[][] getTenantsData() {
return new Object[][] {
{"customer1", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TeNant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TENANT1", "customer1", "serviceType1", "tenant1", "id-1", true},
{"customer1", "serviceType1", "tenant2", "customer1", "serviceType1", "tenant1", "tenant2", false},
{"customer1", "serviceType1", null, "customer1", "serviceType1", "tenant1", "tenant2", true},
{"customer2", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", false},
}
@Test(dataProvider = "getTenantsData")
- public void testGetTenants(String userGlobalCustomerId, String userServiceType, String userTenantName, String serviceGlobalCustomerId,
- String serviceServiceType, String serviceTenantName, String serviceTenantId, boolean expectedIsPermitted) {
+ public void testGetTenants(String userGlobalCustomerId, String userServiceType, String userTenantName,
+ String serviceGlobalCustomerId, String serviceServiceType, String serviceTenantName,
+ String serviceTenantId, boolean expectedIsPermitted) {
GetTenantsResponse[] getTenantsResponses = new GetTenantsResponse[] {new GetTenantsResponse(null, null, serviceTenantName, serviceTenantId, false)};
AaiResponse<GetTenantsResponse[]> aaiResponse = new AaiResponse<>(getTenantsResponses, null, 200);
Mockito.doReturn(aaiResponse).when(aaiClientInterface).getTenants(serviceGlobalCustomerId, serviceServiceType);
- Role role = new Role(null, userGlobalCustomerId, userServiceType, userTenantName);
- RoleValidator roleValidator = RoleValidator.by(Collections.singletonList(role), false);
- AaiResponse<GetTenantsResponse[]> actualTenants = aaiService.getTenants(serviceGlobalCustomerId, serviceServiceType, roleValidator);
+
+ RoleValidator roleValidatorMock = mock(RoleValidator.class);
+ when(roleValidatorMock.isTenantPermitted(
+ eq(userGlobalCustomerId), eq(userServiceType),
+ (userTenantName == null) ? anyString() : eq(userTenantName))
+ ).thenReturn(true);
+
+ AaiResponse<GetTenantsResponse[]> actualTenants = aaiService.getTenants(serviceGlobalCustomerId, serviceServiceType, roleValidatorMock);
assertThat(actualTenants.getT(), arrayWithSize(1));
assertThat(actualTenants.getT()[0].tenantName, equalTo(serviceTenantName));
assertThat(anyMatch, equalTo(expectedMatch));
}
+ @DataProvider
+ public static Object[][] dataToDestroy() {
+ return new Object[][]{
+ {"nothing"}, {"relationship-list"}, {"relationship"}, {"relationship-data"} ,{"owning-entity-id"}
+ };
+ }
+
+
+ @Test(dataProvider = "dataToDestroy")
+ public void relatedOwningEntityId_givenInstanceAndOptionalError_extractCorrectlyOrReturnNull(String dataToDestroy) throws JsonProcessingException {
+ ServiceInstance serviceInstance = new ObjectMapper().readValue((""
+ + "{ "
+ + " \"service-instance-id\": \"5d521981-33be-4bb5-bb20-5616a9c52a5a\", "
+ + " \"service-instance-name\": \"dfgh\", "
+ + " \"service-type\": \"\", "
+ + " \"service-role\": \"\", "
+ + " \"environment-context\": \"null\", "
+ + " \"workload-context\": \"null\", "
+ + " \"model-invariant-id\": \"331a194d-9248-4533-88bc-62c812ccb5c1\", "
+ + " \"model-version-id\": \"171b3887-e73e-479d-8ef8-2690bf74f2aa\", "
+ + " \"resource-version\": \"1508832105498\", "
+ + " \"orchestration-status\": \"Active\", "
+ + " \"relationship-list\": { "
+ + " \"relationship\": [ "
+ + " { "
+ + " \"related-to\": \"project\", "
+ + " \"related-link\": \"/aai/v11/business/projects/project/Kennedy\", "
+ + " \"relationship-data\": [ "
+ + " { "
+ + " \"relationship-key\": \"project.project-name\", "
+ + " \"relationship-value\": \"Kennedy\" "
+ + " } "
+ + " ] "
+ + " }, "
+ + " { "
+ + " \"related-to\": \"owning-entity\", "
+ + " \"related-link\": \"/aai/v11/business/owning-entities/owning-entity/4d4ecf59-41f1-40d4-818d-885234680a42\", "
+ + " \"relationship-data\": [ "
+ + " { "
+ + " \"relationship-key\": \"owning-entity.owning-entity-id\", "
+ + " \"relationship-value\": \"4d4ecf59-41f1-40d4-818d-885234680a42\" "
+ + " } "
+ + " ] "
+ + " } "
+ + " ] "
+ + " } "
+ + "}").replace(dataToDestroy, "omitted"), ServiceInstance.class);
+
+ if (dataToDestroy.equals("nothing")) {
+ assertThat(aaiService.relatedOwningEntityId(serviceInstance), is("4d4ecf59-41f1-40d4-818d-885234680a42"));
+ } else {
+ assertThat(aaiService.relatedOwningEntityId(serviceInstance), is(nullValue()));
+ }
+ }
+
+ @Test
+ public void testGetServicesByOwningEntityId() {
+
+ //given
+ List<String> owningEntityIds = ImmutableList.of("43b8a85a-0421-4265-9069-117dd6526b8a", "26dcc4aa-725a-447d-8346-aa26dfaa4eb7");
+ OwningEntityResponse owningEntityResponse = TestUtils.readJsonResourceFileAsObject("/responses/aai/listServicesByOwningEntity.json", OwningEntityResponse.class);
+ when(aaiClientInterface.getServicesByOwningEntityId(owningEntityIds)).thenReturn(new AaiResponse<>(owningEntityResponse, "", 200));
+ RoleValidator roleValidator = createAlwaysTrueRoleValidator();
+
+ //when
+ List<ServiceInstanceSearchResult> result = aaiService.getServicesByOwningEntityId(owningEntityIds, roleValidator);
+
+ //then
+ ServiceInstanceSearchResult expected1 = new ServiceInstanceSearchResult(
+ "af9d52f9-13b2-4657-a198-463677f82dc0", "256cddb4-3aa1-43cc-a08f-315bb50b275e", "MSO-dev-service-type", "xbghrftgr_shani", null, null, null, "43b8a85a-0421-4265-9069-117dd6526b8a", true);
+ ServiceInstanceSearchResult expected2 = new ServiceInstanceSearchResult(
+ "49769492-5def-4c89-8e73-b236f958fa40", "e02fd6f2-7fc2-434b-a92d-15abdb24b68d", "JUST-another-service-type", "fghghfhgf", null, null, null, "43b8a85a-0421-4265-9069-117dd6526b8a", true);
+ ServiceInstanceSearchResult expected3 = new ServiceInstanceSearchResult(
+ "1d8fd482-2f53-4d62-a7bd-20e4bab14c45", "256cddb4-3aa1-43cc-a08f-315bb50b275e", "MSO-dev-service-type", "Bryant", null, null, null, "26dcc4aa-725a-447d-8346-aa26dfaa4eb7", true);
+
+ assertThat(result, jsonEquals(ImmutableList.of(expected1, expected2, expected3)).when(IGNORING_ARRAY_ORDER).whenIgnoringPaths("[*].subscriberName")); //ignore in array
+ }
+
+ @NotNull
+ private RoleValidator createAlwaysTrueRoleValidator() {
+ RoleValidator roleValidator = mock(RoleValidator.class);
+ when(roleValidator.isServicePermitted(any(WithPermissionProperties.class))).thenReturn(true);
+ return roleValidator;
+ }
+
+ @Test
+ public void testGetServicesByProjectNames() {
+
+ //given
+ List<String> projectNames = ImmutableList.of("x1", "y2");
+ ProjectResponse projectResponse = TestUtils.readJsonResourceFileAsObject("/responses/aai/listServicesByProject.json", ProjectResponse.class);
+ when(aaiClientInterface.getServicesByProjectNames(projectNames)).thenReturn(new AaiResponse<>(projectResponse, "", 200));
+ RoleValidator roleValidator = createAlwaysTrueRoleValidator();
+
+ //when
+ List<ServiceInstanceSearchResult> result = aaiService.getServicesByProjectNames(projectNames, roleValidator);
+
+ //then
+ ServiceInstanceSearchResult expected1 = new ServiceInstanceSearchResult(
+ "3f826016-3ac9-4928-9561-beee75fd91d5", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", "Emanuel", "Lital_SRIOV2_001", null, null, null, null, true);
+ ServiceInstanceSearchResult expected2 = new ServiceInstanceSearchResult(
+ "7e4f8130-5dee-47c4-8770-1abc5f5ded83", "3d15d7ea-4174-49b6-89ec-e569381f7231", "vMOG", "justAname", null, null, null, null, true);
+ ServiceInstanceSearchResult expected3 = new ServiceInstanceSearchResult(
+ "ff2d9326-1ef5-4760-aba0-0eaf372ae675", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", "Yoda", "anotherName", null, null, null, null, true);
+
+ assertThat(result, jsonEquals(ImmutableList.of(expected1, expected2, expected3)).when(IGNORING_ARRAY_ORDER).whenIgnoringPaths("[*].subscriberName")); //ignore in array
+ }
+
}
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
-import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import org.onap.vid.model.serviceInstantiation.Vnf;
import org.onap.vid.mso.RestObject;
import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
import org.onap.vid.mso.rest.AsyncRequestStatus;
import org.onap.vid.mso.rest.RequestStatus;
import org.onap.vid.properties.Features;
testApi,
instanceId,
action.name(),
- UUID.randomUUID().toString(), null, null, null);
+ UUID.randomUUID().toString(), null, null, null, null);
}
private List<Map<String,String>> createInstanceParams() {
return instanceParams;
}
- protected VfModule createVfModule(String modelName, String modelVersionId, String modelCustomizationId,
- List<Map<String, String>> instanceParams, Map<String, String> supplementaryParams, String instanceName, String volumeGroupInstanceName, boolean isAlacarte) {
+ protected VfModule createVfModule(
+ String modelName, String modelVersionId, String modelCustomizationId,
+ List<Map<String, String>> instanceParams, List<UserParamNameAndValue> supplementaryParams, String instanceName,
+ String volumeGroupInstanceName, boolean isAlacarte, Boolean usePreload) {
ModelInfo vfModuleInfo = new ModelInfo();
vfModuleInfo.setModelType("vfModule");
vfModuleInfo.setModelName(modelName);
vfModuleInfo.setModelInvariantId("22222222-f63c-463e-ba94-286933b895f9");
vfModuleInfo.setModelVersion("10.0");
return new VfModule(vfModuleInfo, instanceName, volumeGroupInstanceName, Action.Create.name(), "mdt1", null,
- "88a6ca3ee0394ade9403f075db23167e", instanceParams, supplementaryParams, false, true, null, UUID.randomUUID().toString(), null, null,
- null, null, null);
+ "88a6ca3ee0394ade9403f075db23167e", instanceParams, supplementaryParams, false,
+ usePreload, null, UUID.randomUUID().toString(), null, null,
+ null, null, null, "originalName");
}
return new VfModule(vfModuleInfo, instanceName, volumeGroupInstanceName, Action.Create.name(), null, null, null,
instanceParams, supplementaryParams, false, false, null, UUID.randomUUID().toString(), null,
- null, null, null, null);
+ null, null, null, null, "originalName");
}
protected ModelInfo createVfModuleModelInfo(String modelName, String modelVersion, String modelVersionId, String modelInvariantId, String modelCustomizationId, String modelCustomizationName) {
}
protected VfModule createVfModuleForReplace(ModelInfo vfModuleModelInfo, String instanceName,
- String lcpCloudRegionId, String tenantId, Boolean retainAssignments, Boolean retainVolumeGroups, Map<String, String> supplementaryParams) {
+ String lcpCloudRegionId, String tenantId, Boolean retainAssignments, Boolean retainVolumeGroups, List<UserParamNameAndValue> supplementaryParams) {
return new VfModule( vfModuleModelInfo, instanceName, null, Action.Upgrade.name(), lcpCloudRegionId, null, tenantId,
- null, supplementaryParams, true, null, null, UUID.randomUUID().toString(), null, null, retainAssignments, retainVolumeGroups, null);
+ null, supplementaryParams, true, null, null, UUID.randomUUID().toString(), null, null, retainAssignments, retainVolumeGroups, null, "originalName");
}
protected ModelInfo createVnfModelInfo(boolean isAlacarte) {
Map<String, Map<String, VfModule>> vfModules = new HashMap<>();
List<Map<String, String>> instanceParams1 = ImmutableList.of((ImmutableMap.of("vmx_int_net_len", "24")));
- VfModule vfModule1 = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME, instanceParams1, new HashMap<>(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vPE_BV_base" : null), null, isAlacarte);
+ VfModule vfModule1 = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME,
+ instanceParams1, emptyList(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vPE_BV_base" : null), null, isAlacarte, true);
List<Map<String, String>> instanceParams2 = ImmutableList.of(vfModuleInstanceParamsMap);
- VfModule vfModule2 = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1", VF_MODULE_1_MODEL_VERSION_ID, VF_MODULE_1_MODEL_CUSTOMIZATION_NAME, instanceParams2, new HashMap<>(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion": null), (isUserProvidedNaming ? "myVgName" : null), isAlacarte);
+ VfModule vfModule2 = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1", VF_MODULE_1_MODEL_VERSION_ID, VF_MODULE_1_MODEL_CUSTOMIZATION_NAME,
+ instanceParams2, emptyList(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion": null), (isUserProvidedNaming ? "myVgName" : null), isAlacarte, true);
String vfModuleModelName = vfModule1.getModelInfo().getModelName();
vfModules.put(vfModuleModelName, new LinkedHashMap<>());
Vnf vnf = new Vnf(vnfModelInfo, "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", (isUserProvidedNaming ? VNF_NAME : null), Action.Create.name(),
"platformName", "mdt1", null, "88a6ca3ee0394ade9403f075db23167e", vnfInstanceParams,"lineOfBusinessName" , false, null, vfModules,
- UUID.randomUUID().toString(), null, null, null);
+ UUID.randomUUID().toString(), null, null, null, "originalName");
vnfs.put(vnf.getModelInfo().getModelName(), vnf);
return vnfs;
"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", null, "MOG", lcpCloudRegionId, null, tenantId,
null, null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, instanceParams, false, 1, false, false,
null, null, null, null, null, null,
- new VidNotions(InstantiationUI.TRANSPORT_SERVICE, ModelCategory.Transport, InstantiationUI.TRANSPORT_SERVICE, InstantiationType.Macro)
+ new VidNotions(InstantiationUI.TRANSPORT_SERVICE, ModelCategory.Transport, InstantiationUI.TRANSPORT_SERVICE, InstantiationType.Macro), "originalName"
);
return serviceInstantiation;
}
details->new Network(createNetworkModelInfo(isALaCarte, details.modelCustomizationId), "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb",
details.name, Action.Create.name(),
"platformName", "mdt1", null, "88a6ca3ee0394ade9403f075db23167e", instanceParams,"lineOfBusinessName" ,
- false, null, UUID.randomUUID().toString(), null, null, null));
+ false, null, UUID.randomUUID().toString(), null, null, null, "originalName"));
// I can't tell why compiler don't like the statement if it's only one line...
return networkStream.collect(Collectors.toMap(network -> network.getModelInfo().getModelCustomizationId(), network -> network));
}
modelInfo.setModelVersion("10.0");
return new InstanceGroup(modelInfo, (isUserProvidedNaming ? VNF_GROUP_NAME : null), action.name(), false, null, emptyMap(), UUID.randomUUID().toString(), null, null,
- null);
+ null, "originalName");
}
protected ModelInfo createServiceModelInfo() {
import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
import static net.javacrumbs.jsonunit.JsonAssert.whenIgnoringPaths;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItem;
import static org.onap.vid.job.Job.JobStatus.PENDING;
import static org.onap.vid.job.Job.JobStatus.STOPPED;
import static org.onap.vid.testUtils.TestUtils.generateRandomAlphaNumeric;
+import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@ContextConfiguration(classes = {DataSourceConfig.class, SystemProperties.class, MockedAaiClientAndFeatureManagerConfig.class})
public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseTest {
-
-
@Mock
private JobAdapter jobAdapterMock;
public void whenLcpRegionNotEmpty_thenCloudRegionIdOfResourceIsLegacy() {
String legacyCloudRegion = "legacyCloudRegion";
Vnf vnf = new Vnf(new ModelInfo(), null, null, Action.Create.name(), null, "anyCloudRegion", legacyCloudRegion,
- null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null);
+ null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null, "originalName");
assertThat(vnf.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
}
String legacyCloudRegion = "legacyCloudRegion";
ServiceInstantiation service = new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
null, null, "anyCloudRegion", legacyCloudRegion, null, null, null, null, null, null, null, null, null,
- false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null);
+ false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null, "originalName");
assertThat(service.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
}
return new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null,
false, 1, false, isALaCarte, null, null, action.name(),
- UUID.randomUUID().toString(), null, null, null);
+ UUID.randomUUID().toString(), null, null, null, "originalName");
}
@DataProvider
String message = "Failed to create service instance";
return new Object[][]{
{500, message},
- {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"}
+ {400, "{\"requestError\":{\"serviceException\":{\"messageId\":\"SVC0002\",\"text\":\"" + message + "\"}}}"},
+ {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"},
};
}
{
String path = asyncInstantiationBL.getVfModuleReplacePath("myService", "myVNF", "myVFModule");
assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myService/vnfs/myVNF/vfModules/myVFModule/replace"));
+ }
+ @Test
+ public void whenCallClearStatusFromRequest_isFailedAndStatusAreRemoved() throws JsonProcessingException {
+ ServiceInstantiation serviceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
+ "{"
+ + " \"modelInfo\": {"
+ + " \"modelType\": \"service\""
+ + " },"
+ + " \"isFailed\": true,"
+ + " \"statusMessage\": \"some status\","
+ + " \"vnfs\": {"
+ + " \"vProbe_NC_VNF\": {"
+ + " \"modelInfo\": {"
+ + " \"modelType\": \"vnf\""
+ + " },"
+ + " \"isFailed\": true,"
+ + " \"statusMessage\": \"other status\""
+ + " }"
+ + " }"
+ + "}",
+ ServiceInstantiation.class);
+ asyncInstantiationBL.clearStatusFromRequest(serviceInstantiation);
+ assertThat(serviceInstantiation, allOf(
+ jsonPartEquals("isFailed", false),
+ jsonPartEquals("statusMessage", null),
+ jsonPartEquals("vnfs.vProbe_NC_VNF.isFailed", false),
+ jsonPartEquals("vnfs.vProbe_NC_VNF.statusMessage", null)
+ ));
}
+
}
package org.onap.vid.services;
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anEmptyMap;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.nullValue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import org.mockito.InjectMocks;
import org.mockito.Mock;
+import org.onap.vid.asdc.beans.Service;
import org.onap.vid.dal.AsyncInstantiationRepository;
import org.onap.vid.model.ModelUtil;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiationTemplate;
import org.onap.vid.model.serviceInstantiation.Vnf;
+import org.onap.vid.properties.Features;
import org.onap.vid.testUtils.TestUtils;
+import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import org.togglz.core.manager.FeatureManager;
public class InstantiationTemplatesServiceTest {
@Mock
private ModelUtil modelUtil;
+ @Mock
+ private FeatureManager featureManager;
+
@InjectMocks
private InstantiationTemplatesService instantiationTemplatesService;
TestUtils.initMockitoMocks(this);
}
+ @AfterMethod
+ public void resetMocks() {
+ reset(featureManager);
+ }
+
@Test
public void getJobRequestAsTemplate_whenIsCalled_asyncInstantiationRepositoryGetJobRequestIsInvoked() {
UUID jobId = UUID.randomUUID();
assertThat(result, hasProperty("existingVRFCounterMap", anEmptyMap()));
}
+ @DataProvider
+ public static Object[][] isTemplatesExistsByGivenServiceUuid() {
+ return new Object[][]{{"1",TRUE},
+ {"3",FALSE}};
+ }
+
+ @Test(dataProvider = "isTemplatesExistsByGivenServiceUuid")
+ public void setInServicesTemplateValue_givenServiceWithServiceModelId_thenIsTemplateExistsIsEatherTrueOrFalse(String givenUuid, Boolean expectedTemplatesExist){
+
+ Service service = new Service();
+ service.setUuid(givenUuid);
+
+ Service newService = instantiationTemplatesService.setTemplateExistForService(service, ImmutableSet.of("1", "2"));
+ assertThat(newService.getIsInstantiationTemplateExists(), is(expectedTemplatesExist));
+ }
+
+ @Test
+ public void setTemplatesExistance_givenCollection__flagIsActive_thenSameCollectionReturnedWithTemplateExistsProperty(){
+ when(featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)).thenReturn(true);
+ when(asyncInstantiationRepository.getAllTemplatesServiceModelIds()).thenReturn(ImmutableSet.of("1", "2"));
+ Collection<Service> actualCollection = instantiationTemplatesService.setOnEachServiceIsTemplateExists(createGivenCollection());
+ assertThat(actualCollection, containsInAnyOrder(
+ allOf(hasProperty("uuid", is("1")), hasProperty("isInstantiationTemplateExists", is(true))),
+ allOf(hasProperty("uuid", is("3")), hasProperty("isInstantiationTemplateExists", is(false)))
+ ));
+ }
+
+ @Test
+ public void setTemplatesExistance_givenCollection_flagIsNotActive_thenTemplatesExistNotAdded(){
+ when(featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)).thenReturn(false);
+ Collection<Service> actualCollection = instantiationTemplatesService.setOnEachServiceIsTemplateExists(createGivenCollection());
+ assertThat("was " + actualCollection, actualCollection, containsInAnyOrder(
+ allOf(hasProperty("uuid", is("1")), hasProperty("isInstantiationTemplateExists", is(false))),
+ allOf(hasProperty("uuid", is("3")), hasProperty("isInstantiationTemplateExists", is(false)))
+ ));
+ }
+
+ private Collection<Service> createGivenCollection(){
+ Service service1 = new Service();
+ Service service2 = new Service();
+ service1.setUuid("1");
+ service2.setUuid("3");
+ return ImmutableList.of(service1, service2);
+ }
+
}
package org.onap.vid.services;
import static com.google.common.collect.Maps.newHashMap;
+import static java.util.Collections.EMPTY_LIST;
+import static java.util.Collections.EMPTY_MAP;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonNodeAbsent;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.onap.vid.mso.model.NetworkInstantiationRequestDetails;
import org.onap.vid.mso.model.ServiceDeletionRequestDetails;
import org.onap.vid.mso.model.ServiceInstantiationRequestDetails;
-import org.onap.vid.mso.model.UserParamMap;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
import org.onap.vid.mso.model.VfModuleMacro;
import org.onap.vid.mso.model.VfModuleOrVolumeGroupRequestDetails;
import org.onap.vid.mso.model.VnfInstantiationRequestDetails;
private void createMacroServiceInfo_WithUserProvidedNamingFalse_ServiceInfoIsAsExpected(boolean withVfmodules, boolean disabledHoming) throws IOException {
ServiceInstantiation serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(true,
- createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, Collections.EMPTY_LIST, false),
+ createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, EMPTY_LIST, false),
1,
false, PROJECT_NAME, true);
URL resource;
msoRequestBuilder.generateMacroServiceInstantiationRequest(null, serviceInstantiationPayload, serviceInstantiationPayload.getInstanceName(), "az2016");
String expected = IOUtils.toString(resource, "UTF-8");
- MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
+ assertThat(result, jsonEquals(expected));
}
@Test
}
private ServiceInstantiation generateALaCarteServiceDeletionPayload() {
- return generateMockAlaCarteServiceDeletionPayload(false, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
+ return generateMockAlaCarteServiceDeletionPayload(false, EMPTY_MAP, EMPTY_MAP, EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
}
@Test
}
private ServiceInstantiation generateServiceDeletionPayload() {
- return generateMockServiceDeletionPayload(false, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
+ return generateMockServiceDeletionPayload(false, EMPTY_MAP, EMPTY_MAP, EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
}
@DataProvider
public static Object[][] testBuildVnfInstanceParamsDataProvider(Method test) {
return new Object[][]{
{
- Collections.EMPTY_LIST,
+ EMPTY_LIST,
ImmutableList.of(
ImmutableList.of(ImmutableMap.of("k1", "v1", "k2", "v2")),
ImmutableList.of(ImmutableMap.of("k3", "v3", "k2", "v2"))
ImmutableList.of(
ImmutableList.of(ImmutableMap.of("k1", "v1", "k2", "v2")),
ImmutableList.of(ImmutableMap.of("k3", "v3", "k2", "v2")),
- ImmutableList.of(Collections.EMPTY_MAP),
- Collections.singletonList(null)
+ ImmutableList.of(EMPTY_MAP),
+ singletonList(null)
),
ImmutableList.of(ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "j1", "w1"))
},
{
- Collections.EMPTY_LIST,
+ EMPTY_LIST,
Arrays.asList(null, null),
- Collections.EMPTY_LIST //mso is expect to empty list and not list with empty map
+ EMPTY_LIST //mso is expect to empty list and not list with empty map
},
{
- ImmutableList.of(Collections.EMPTY_MAP),
+ ImmutableList.of(EMPTY_MAP),
ImmutableList.of(
- ImmutableList.of(Collections.EMPTY_MAP),
- ImmutableList.of(Collections.EMPTY_MAP)
+ ImmutableList.of(EMPTY_MAP),
+ ImmutableList.of(EMPTY_MAP)
),
- Collections.EMPTY_LIST //mso is expect to empty list and not list with empty map
+ EMPTY_LIST //mso is expect to empty list and not list with empty map
}
};
}
@DataProvider
public static Object[][] vfModuleRequestDetails(Method test) {
return new Object[][]{
- {"cc3514e3-5a33-55df-13ab-12abad84e7cc", true, "/payload_jsons/vfmodule_instantiation_request.json"},
- {null, true, "/payload_jsons/vfmodule_instantiation_request_without_volume_group.json"},
- {null, false, "/payload_jsons/vfmodule_instantiation_request_without_instance_name.json"}
+ {"cc3514e3-5a33-55df-13ab-12abad84e7cc", true, false, "/payload_jsons/vfmodule_instantiation_request.json"},
+ {null, true, null, "/payload_jsons/vfmodule_instantiation_request_without_volume_group.json"},
+ {null, false, true, "/payload_jsons/vfmodule_instantiation_request_without_instance_name.json"}
};
}
@Test(dataProvider = "vfModuleRequestDetails")
- public void createVfModuleRequestDetails_detailsAreAsExpected(String volumeGroupInstanceId, boolean isUserProvidedNaming, String fileName) throws IOException {
+ public void createVfModuleRequestDetails_detailsAreAsExpected(String volumeGroupInstanceId, boolean isUserProvidedNaming, Boolean usePreload, String fileName) throws IOException {
ModelInfo siModelInfo = createServiceModelInfo();
ModelInfo vnfModelInfo = createVnfModelInfo(true);
List<Map<String, String>> instanceParams = ImmutableList.of(ImmutableMap.of("vmx_int_net_len", "24",
"vre_a_volume_size_0", "120"));
- Map<String, String> supplementaryParams = ImmutableMap.of("vre_a_volume_size_0", "100",
- "availability_zone_0", "mtpocdv-kvm-az01");
+ List<UserParamNameAndValue> supplementaryParams = ImmutableList.of(
+ new UserParamNameAndValue("vre_a_volume_size_0", "100"),
+ new UserParamNameAndValue("availability_zone_0", "mtpocdv-kvm-az01")
+ );
+
VfModule vfModule = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1", "56e2b103-637c-4d1a-adc8-3a7f4a6c3240",
"72d9d1cd-f46d-447a-abdb-451d6fb05fa8", instanceParams, supplementaryParams,
- (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion" : null), "myVgName", true);
+ (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion" : null), "myVgName", true, usePreload);
String serviceInstanceId = "aa3514e3-5a33-55df-13ab-12abad84e7aa";
String vnfInstanceId = "bb3514e3-5a33-55df-13ab-12abad84e7bb";
final RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> result = msoRequestBuilder.generateVfModuleInstantiationRequest(
vfModule, siModelInfo, serviceInstanceId,
vnfModelInfo, vnfInstanceId, volumeGroupInstanceId, "pa0916", "VNF_API");
- MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
- }
-
- @DataProvider
- public static Object[][] expectedAggregatedParams() {
- return new Object[][]{
- {ImmutableMap.of("a", "b", "c", "d"), ImmutableMap.of("e", "f", "g", "h"), ImmutableList.of(ImmutableMap.of("c", "d", "a", "b", "e", "f", "g", "h"))},
- {ImmutableMap.of("a", "b", "c", "g"), ImmutableMap.of("c", "d", "e", "f"), ImmutableList.of(ImmutableMap.of("a", "b", "c", "d", "e", "f"))},
- {ImmutableMap.of(), ImmutableMap.of("c", "d", "e", "f"), ImmutableList.of(ImmutableMap.of("c", "d", "e", "f"))},
- {ImmutableMap.of("a", "b", "c", "g"), ImmutableMap.of(), ImmutableList.of(ImmutableMap.of("a", "b", "c", "g"))},
- {ImmutableMap.of(), ImmutableMap.of(), ImmutableList.of()},
- {null, ImmutableMap.of(), ImmutableList.of()},
- {ImmutableMap.of(), null, ImmutableList.of()},
- };
- }
-
- @Test(dataProvider = "expectedAggregatedParams")
- public void testAggregateInstanceParamsAndSuppFile(Map<String, String> instanceParams, Map<String, String> suppParams, List<UserParamMap<String, String>> expected) {
- List<UserParamMap<String, String>> aggParams = msoRequestBuilder.aggregateAllInstanceParams(instanceParams, suppParams);
- assertThat("Aggregated params are not as expected", aggParams, equalTo(expected));
+ assertThat(result, jsonEquals(expected).when(IGNORING_ARRAY_ORDER));
}
@Test
VfModule vfModule = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1",
"56e2b103-637c-4d1a-adc8-3a7f4a6c3240",
"72d9d1cd-f46d-447a-abdb-451d6fb05fa8",
- Collections.emptyList(),
- Collections.emptyMap(),
+ emptyList(),
+ emptyList(),
"vmxnjr001_AVPN_base_vRE_BV_expansion",
"myVgName",
+ true,
true);
vfModule.getModelInfo().setModelInvariantId("ff5256d2-5a33-55df-13ab-12abad84e7ff");
vfModule.getModelInfo().setModelVersion("1");
@Test(dataProvider = "expectedNetworkRequestDetailsParameters")
public void createNetworkRequestDetails_detailsAreAsExpected(String networkName, String filePath) throws IOException {
- List<NetworkDetails> networkDetails = Collections.singletonList(new NetworkDetails(networkName, "ab153b6e-c364-44c0-bef6-1f2982117f04"));
+ List<NetworkDetails> networkDetails = singletonList(new NetworkDetails(networkName, "ab153b6e-c364-44c0-bef6-1f2982117f04"));
final List<Network> networksList = new ArrayList<>(createNetworkList(null, networkDetails, true).values());
ModelInfo siModelInfo = createServiceModelInfo();
String serviceInstanceId = "aa3514e3-5a33-55df-13ab-12abad84e7aa";
@Test
public void checkIfNullProjectNameSentToMso() {
ServiceInstantiation serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(true,
- createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, Collections.EMPTY_LIST, false),
+ createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, EMPTY_LIST, false),
1,
false, null, false);
RequestDetailsWrapper<ServiceInstantiationRequestDetails> result =
JsonNode jsonNode = new ObjectMapper().valueToTree(result.requestDetails);
Assert.assertTrue(jsonNode.get("project").isNull());
serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(true,
- createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, Collections.EMPTY_LIST, false),
+ createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, EMPTY_LIST, false),
1,
false, "not null", false);
result = msoRequestBuilder.generateMacroServiceInstantiationRequest(null, serviceInstantiationPayload, serviceInstantiationPayload.getInstanceName(), "az2016");
"}";
Vnf vnfDetails = new Vnf(createVnfModelInfo(true), "productFamily", "instanceName", Action.Delete.name(), "platform", "AAIAIC25", null,
"092eb9e8e4b7412e8787dd091bc58e86", null, null, false, "VNF_INSTANCE_ID", null, UUID.randomUUID().toString(), null, null,
- null);
+ null, "originalName");
RequestDetailsWrapper<VnfInstantiationRequestDetails> result =
msoRequestBuilder.generateDeleteVnfRequest(vnfDetails, "az2018");
MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
" }" +
" }" +
"}";
- VfModule vfModuleDetails = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME, null, new HashMap<>(), "vmxnjr001_AVPN_base_vPE_BV_base", null, true);
+ VfModule vfModuleDetails = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME,
+ null, emptyList(), "vmxnjr001_AVPN_base_vPE_BV_base", null, true, true);
RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> result =
msoRequestBuilder.generateDeleteVfModuleRequest(vfModuleDetails, "az2018");
MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
@Test
public void generateReplaceVfModuleRequest_whenThereAreSupplementaryParams_thenTheyAreAddToUserParams() {
- String expectedParams = "[{"
- + " \"vre_a_volume_size_0\" : \"100\","
- + " \"vmx_int_net_len\" : \"24\","
- + " \"availability_zone_0\": \"abc\""
- + " }]";
-
- Map<String, String> supplementaryParams = ImmutableMap.of(
- "vre_a_volume_size_0", "100",
- "vmx_int_net_len", "24",
- "availability_zone_0", "abc"
+ String expectedParams = "["
+ + " {"
+ + " \"name\": \"vre_a_volume_size_0\","
+ + " \"value\": \"100\""
+ + " },"
+ + " {"
+ + " \"name\": \"vmx_int_net_len\","
+ + " \"value\": \"24\""
+ + " },"
+ + " {"
+ + " \"name\": \"availability_zone_0\","
+ + " \"value\": \"abc\""
+ + " }"
+ + " ]";
+
+ List<UserParamNameAndValue> supplementaryParams = ImmutableList.of(
+ new UserParamNameAndValue( "vre_a_volume_size_0", "100"),
+ new UserParamNameAndValue("vmx_int_net_len", "24"),
+ new UserParamNameAndValue("availability_zone_0", "abc")
);
assertThat(generatedVfModuleReplaceRequest(null, null, supplementaryParams),
}
private RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> generatedVfModuleReplaceRequest(
- Boolean retainAssignments, Boolean retainVolumeGroups, Map<String, String> supplementaryParams) {
+ Boolean retainAssignments, Boolean retainVolumeGroups, List<UserParamNameAndValue> supplementaryParams) {
when(featureManager.isActive(Features.FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST)).thenReturn(true);
when(aaiClient.getCloudOwnerByCloudRegionId("regionOne")).thenReturn("irma-aic");
--- /dev/null
+package org.onap.vid.services
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue
+import org.testng.annotations.DataProvider
+import org.testng.annotations.Test
+
+class UserParamsContainerTest {
+
+ @DataProvider
+ fun userParamsDataProvider(): Array<Array<Any?>>? {
+ return arrayOf(
+ arrayOf<Any?>(
+ mapOf("a" to "b", "c" to "d"),
+ listOf(UserParamNameAndValue("e", "f"), UserParamNameAndValue("g", "h")),
+ mapOf("c" to "d", "a" to "b", "e" to "f", "g" to "h")
+ ),
+ arrayOf<Any?>(
+ mapOf("a" to "b", "c" to "g"),
+ listOf(UserParamNameAndValue("c", "d") , UserParamNameAndValue("e", "f")),
+ mapOf("c" to "d", "a" to "b", "e" to "f")
+ ),
+ arrayOf<Any?>(
+ emptyMap<String,String>(),
+ listOf(UserParamNameAndValue("c", "d"), UserParamNameAndValue("e", "f")),
+ mapOf("c" to "d", "e" to "f")
+ ),
+ arrayOf<Any?>(
+ mapOf("a" to "b", "c" to "d"),
+ emptyList<UserParamNameAndValue>(),
+ mapOf("a" to "b", "c" to "d")
+ ),
+ arrayOf<Any?>(
+ emptyMap<String,String>(),
+ emptyList<UserParamNameAndValue>(),
+ emptyMap<String,String>()
+ ),
+ arrayOf(
+ null,
+ emptyList<UserParamNameAndValue>(),
+ emptyMap<String,String>()
+ ),
+ arrayOf<Any?>(
+ emptyMap<String,String>(),
+ null,
+ emptyMap<String,String>()
+ )
+ )
+ }
+
+ @Test(dataProvider = "userParamsDataProvider")
+ fun testUserParamsConvertorCtor(instanceParams: Map<String, String>?, suppParams: List<UserParamNameAndValue>?, expected: Map<String, String>) {
+ val aggParams: Map<String, String> = UserParamsContainer(instanceParams, suppParams).params
+ MatcherAssert.assertThat("Aggregated params are not as expected", aggParams, equalTo(expected))
+ }
+}
\ No newline at end of file
package org.onap.vid.testUtils;
import static com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper;
-import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
import static org.apache.commons.beanutils.PropertyUtils.getPropertyDescriptors;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.text.CharacterPredicates.DIGITS;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
}
public static String[] allPropertiesOf(Class<?> aClass) {
- return Arrays.stream(getPropertyDescriptors(aClass))
+ return getPropertyDescriptorsRecursively(aClass).stream()
.map(PropertyDescriptor::getDisplayName)
+ .distinct()
.toArray(String[]::new);
}
+ private static List<PropertyDescriptor> getPropertyDescriptorsRecursively(Class<?> aClass) {
+ List<PropertyDescriptor> result = new LinkedList<>();
+
+ for (Class<?> i = aClass; i != null && i != Object.class; i = i.getSuperclass()) {
+ Collections.addAll(result, getPropertyDescriptors(i));
+ }
+
+ return result;
+ }
+
private static <T> List<String> allStringPropertiesOf(T object) {
- return Arrays.stream(getPropertyDescriptors(object.getClass()))
+ return getPropertyDescriptorsRecursively(object.getClass()).stream()
.filter(descriptor -> descriptor.getPropertyType().isAssignableFrom(String.class))
.map(PropertyDescriptor::getDisplayName)
+ .distinct()
.collect(toList());
}
* @return The modified object
*/
public static <T> T setStringsInStringProperties(T object) {
- try {
- final List<String> stringFields = allStringPropertiesOf(object);
-
- BeanUtils.populate(object, stringFields.stream()
- .collect(toMap(identity(), identity())));
+ allStringPropertiesOf(object).forEach(it -> {
+ try {
+ FieldUtils.writeField(object, it, it, true);
+ } catch (IllegalAccessException e) {
+ // YOLO
+ }
+ });
- return object;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ return object;
}
public static void registerCloudConfigurationValueGenerator() {
--- /dev/null
+FLAG_1810_AAI_LOCAL_CACHE=true
\ No newline at end of file
"instanceId": "VF_MODULE_INSTANCE_ID",
"action": "Create",
"lcpCloudRegionId": "AAIAIC25",
+ "legacyRegion": "some legacy region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
"modelInfo": {
"modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
"provStatus": "Prov Status",
"inMaint": false,
"lcpCloudRegionId": "AAIAIC25",
+ "legacyRegion": "some legacy region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
"modelInfo": {
"modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
"provStatus": "Prov Status",
"inMaint": false,
"lcpCloudRegionId": "AAIAIC25",
+ "legacyRegion": "some legacy region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
"modelInfo": {
"modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
}],
"requestParameters": {
"userParams": [],
+ "usePreload": false,
"testApi": "GR_API"
},
"modelInfo": {
"rollbackOnFailure": false,
"isALaCarte": true,
"collectionResources": {},
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"vidNotions": {
"instantiationUI": "legacy",
"modelCategory": "other",
"retainAssignments": false,
"usePreload" : true,
"userParams": [],
- "testApi": "VNF_API"
+ "testApi": "GR_API"
},
"modelInfo": {
"modelType": "vfModule",
}
],
"requestParameters": {
- "usePreload": true,
- "userParams": [{
- "vre_a_volume_size_0" : "100",
- "vmx_int_net_len" : "24",
- "availability_zone_0": "mtpocdv-kvm-az01"
- }],
+ "usePreload": false,
+ "userParams": [
+ {
+ "name": "vre_a_volume_size_0",
+ "value": "100"
+ },
+ {
+ "name": "vmx_int_net_len",
+ "value": "24"
+ },
+ {
+ "name": "availability_zone_0",
+ "value": "mtpocdv-kvm-az01"
+ }
+ ],
"testApi" : "VNF_API"
}
}
],
"requestParameters": {
"usePreload": true,
- "userParams": [{
- "vre_a_volume_size_0" : "100",
- "vmx_int_net_len" : "24",
- "availability_zone_0": "mtpocdv-kvm-az01"
- }],
+ "userParams": [
+ {
+ "name": "vre_a_volume_size_0",
+ "value": "100"
+ },
+ {
+ "name": "vmx_int_net_len",
+ "value": "24"
+ },
+ {
+ "name": "availability_zone_0",
+ "value": "mtpocdv-kvm-az01"
+ }
+ ],
"testApi" : "VNF_API"
}
}
}
],
"requestParameters": {
- "usePreload": true,
- "userParams": [{
- "vre_a_volume_size_0" : "100",
- "vmx_int_net_len" : "24",
- "availability_zone_0": "mtpocdv-kvm-az01"
- }],
+ "usePreload": false,
+ "userParams": [
+ {
+ "name": "vre_a_volume_size_0",
+ "value": "100"
+ },
+ {
+ "name": "vmx_int_net_len",
+ "value": "24"
+ },
+ {
+ "name": "availability_zone_0",
+ "value": "mtpocdv-kvm-az01"
+ }
+ ],
"testApi" : "VNF_API"
}
}
--- /dev/null
+{
+ "owning-entity": [
+ {
+ "owning-entity-id": "43b8a85a-0421-4265-9069-117dd6526b8a",
+ "owning-entity-name": "Melissa",
+ "resource-version": "1527418700853",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/256cddb4-3aa1-43cc-a08f-315bb50b275e/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/af9d52f9-13b2-4657-a198-463677f82dc0",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "256cddb4-3aa1-43cc-a08f-315bb50b275e"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "MSO-dev-service-type"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "af9d52f9-13b2-4657-a198-463677f82dc0"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "xbghrftgr_shani"
+ }
+ ]
+ },
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/e02fd6f2-7fc2-434b-a92d-15abdb24b68d/service-subscriptions/service-subscription/JUST-another-service-type/service-instances/service-instance/49769492-5def-4c89-8e73-b236f958fa40",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "e02fd6f2-7fc2-434b-a92d-15abdb24b68d"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "JUST-another-service-type"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "49769492-5def-4c89-8e73-b236f958fa40"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "fghghfhgf"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "owning-entity-id": "26dcc4aa-725a-447d-8346-aa26dfaa4eb7",
+ "owning-entity-name": "Kobe",
+ "resource-version": "1527418700844",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/256cddb4-3aa1-43cc-a08f-315bb50b275e/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/1d8fd482-2f53-4d62-a7bd-20e4bab14c45",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "256cddb4-3aa1-43cc-a08f-315bb50b275e"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "MSO-dev-service-type"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "1d8fd482-2f53-4d62-a7bd-20e4bab14c45"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "Bryant"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+{
+ "project": [
+ {
+ "project-name": "x1",
+ "resource-version": "1527026201826",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.Uses",
+ "related-link": "/aai/v12/business/customers/customer/a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb/service-subscriptions/service-subscription/Emanuel/service-instances/service-instance/3f826016-3ac9-4928-9561-beee75fd91d5",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "Emanuel"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "3f826016-3ac9-4928-9561-beee75fd91d5"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "Lital_SRIOV2_001"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "project-name": "y2",
+ "resource-version": "1527026341826",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/3d15d7ea-4174-49b6-89ec-e569381f7231/service-subscriptions/service-subscription/vMOG/service-instances/service-instance/7e4f8130-5dee-47c4-8770-1abc5f5ded83",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "3d15d7ea-4174-49b6-89ec-e569381f7231"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "vMOG"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "7e4f8130-5dee-47c4-8770-1abc5f5ded83"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "justAname"
+ }
+ ]
+ },
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.Uses",
+ "related-link": "/aai/v12/business/customers/customer/a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb/service-subscriptions/service-subscription/Yoda/service-instances/service-instance/ff2d9326-1ef5-4760-aba0-0eaf372ae675",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "Yoda"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "ff2d9326-1ef5-4760-aba0-0eaf372ae675"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "anotherName"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}
major=6
minor=0
-patch=0
+patch=3
base_version=${major}.${minor}.${patch}
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
- <version>4.0.9</version>
+ <version>3.1.5</version>
</dependency>
<dependency>
public static void navigateToUrl(String url) {
try {
- System.out.println("Deleting cookies...");
- deleteCookies();
-
System.out.println("Navigating to URL : " + url);
getDriver().navigate().to(url);
GeneralUIUtils.waitForLoader();
}
public static void waitForLoader(int timeOut) {
- newWait(timeOut).until(ExpectedConditions.invisibilityOfElementLocated(By.className("sdc-loader-background")));
+ newWait(timeOut).until(ExpectedConditions.invisibilityOfElementLocated(By.className("custom-loader-background")));
}
public static void findComponentAndClick(String resourceName) throws Exception {
public static final String DEFAULT_INSTANCE_ID = "f8791436-8d55-4fde-b4d5-72dd2cf13cfb";
protected String cloudOwner = DEFAULT_CLOUD_OWNER;
- public static String getRequestBodyWithTestApiOnly() {
- if (Features.FLAG_ADD_MSO_TESTAPI_FIELD.isActive()) {
- return "" +
- "{" +
- " \"requestDetails\": { " +
- " \"requestParameters\": { " +
- " \"testApi\": \"VNF_API\" " +
- " } " +
- " } " +
- "} " +
- "";
- } else {
- return null;
- }
- }
-
protected String addCloudOwnerIfNeeded() {
return Features.FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST.isActive() ?
"\"cloudOwner\": \"" + cloudOwner + "\"," : "";
package org.onap.simulator.presetGenerator.presets.aai;
import com.google.common.collect.ImmutableMap;
-import org.onap.simulator.presetGenerator.presets.BasePresets.BaseAAIPreset;
-import org.springframework.http.HttpMethod;
-
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BaseAAIPreset;
+import org.springframework.http.HttpMethod;
public class PresetAAIGetModelsByOwningEntity extends BaseAAIPreset {
- String oeName;
+
+ private static final String DEFAULT_OWNING_ENTITY_ID = "43b8a85a-0421-4265-9069-117dd6526b8a";
+ private static final String DEFAULT_SUBSCRIBER_ID = "CAR_2020_ER";
+
+ private String oeName;
+ private String oeId;
+ private String subscriberId;
public PresetAAIGetModelsByOwningEntity(String oeName) {
this.oeName = oeName;
+ this.oeId = DEFAULT_OWNING_ENTITY_ID;
+ this.subscriberId = DEFAULT_SUBSCRIBER_ID;
+ }
+
+ public PresetAAIGetModelsByOwningEntity(String oeName, String oeId, String subscriberId) {
+ this.oeName = oeName;
+ this.oeId = oeId;
+ this.subscriberId = subscriberId;
}
@Override
return "{" +
" \"owning-entity\": [" +
" {" +
- " \"owning-entity-id\": \"43b8a85a-0421-4265-9069-117dd6526b8a\"," +
+ " \"owning-entity-id\": \"" + oeId + "\"," +
" \"owning-entity-name\": \"" + oeName + "\"," +
" \"resource-version\": \"1527418700853\"," +
" \"relationship-list\": {" +
" {" +
" \"related-to\": \"service-instance\"," +
" \"relationship-label\": \"org.onap.relationships.inventory.BelongsTo\"," +
- " \"related-link\": \"/aai/v12/business/customers/customer/CAR_2020_ER/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/af9d52f9-13b2-4657-a198-463677f82dc0\"," +
+ " \"related-link\": \"/aai/v12/business/customers/customer/" + subscriberId + "/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/af9d52f9-13b2-4657-a198-463677f82dc0\"," +
" \"relationship-data\": [" +
" {" +
" \"relationship-key\": \"customer.global-customer-id\"," +
- " \"relationship-value\": \"CAR_2020_ER\"" +
+ " \"relationship-value\": \"" + subscriberId + "\"" +
" }," +
" {" +
" \"relationship-key\": \"service-subscription.service-type\"," +
" {" +
" \"related-to\": \"service-instance\"," +
" \"relationship-label\": \"org.onap.relationships.inventory.BelongsTo\"," +
- " \"related-link\": \"/aai/v12/business/customers/customer/CAR_2020_ER/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/49769492-5def-4c89-8e73-b236f958fa40\"," +
+ " \"related-link\": \"/aai/v12/business/customers/customer/" + DEFAULT_SUBSCRIBER_ID + "/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/49769492-5def-4c89-8e73-b236f958fa40\"," +
" \"relationship-data\": [" +
" {" +
" \"relationship-key\": \"customer.global-customer-id\"," +
- " \"relationship-value\": \"CAR_2020_ER\"" +
+ " \"relationship-value\": \"" + DEFAULT_SUBSCRIBER_ID + "\"" +
" }," +
" {" +
" \"relationship-key\": \"service-subscription.service-type\"," +
" \"requestorId\": \"us16807000\"" +
" }," +
" \"requestParameters\": {" +
- " \"testApi\": \"VNF_API\"" +
+ " \"testApi\": \"GR_API\"" +
" }," +
" \"cloudConfiguration\": {" +
" \"lcpCloudRegionId\": \"hvf6\"," +
" }" +
" ]," +
" \"requestParameters\": {" +
- " \"testApi\": \"VNF_API\"," +
+ " \"testApi\": \"GR_API\"," +
" \"userParams\": []" +
" }" +
" }" +
" \"modelCustomizationName\": \"AIC30_CONTRAIL_BASIC 0\"" +
" }," +
" \"requestParameters\": {" +
- " \"testApi\": \"VNF_API\"," +
+ " \"testApi\": \"GR_API\"," +
" \"userParams\": []" +
" }," +
" \"cloudConfiguration\": {" +
" \"requestorId\": \""+this.requestorId+"\"" +
" }," +
" \"requestParameters\": {" +
- " \"testApi\": \"VNF_API\"," +
+ " \"testApi\": \"GR_API\"," +
" \"subscriptionServiceType\": \"TYLER SILVIA\"," +
" \"aLaCarte\": true," +
" \"userParams\": []" +
" \"requestorId\": \"us16807000\" " +
" }, " +
" \"requestParameters\": { " +
- " \"testApi\": \"VNF_API\", " +
+ " \"testApi\": \"GR_API\", " +
" \"subscriptionServiceType\": \"TYLER SILVIA\", " +
" \"aLaCarte\": true, " +
" \"userParams\": [] " +
" \"requestorId\": \"" + userId + "\" " +
" }, " +
" \"requestParameters\": { " +
- " \"testApi\": \"VNF_API\", " +
+ " \"testApi\": \"GR_API\", " +
" \"subscriptionServiceType\": \"TYLER SILVIA\", " +
" \"aLaCarte\": true, " +
" \"userParams\": [] " +
" \"requestorId\": \"us16807000\" " +
" }, " +
" \"requestParameters\": { " +
- " \"testApi\": \"VNF_API\", " +
+ " \"testApi\": \"GR_API\", " +
" \"subscriptionServiceType\": \"TYLER SILVIA\", " +
" \"aLaCarte\": true, " +
" \"userParams\": [] " +
" ]," +
" \"requestParameters\": {" +
" \"userParams\": []," +
- " \"testApi\": \"VNF_API\"" +
+ " \"testApi\": \"GR_API\"" +
" }" +
" }" +
"}";
+ " }" + addRelatedInstance()
+ " ],"
+ " \"requestParameters\": {"
- + " \"userParams\": [{"
- + " \"param\": \"ABCD\","
- + " \"vnf_instance_name\": \"sample\""
+ + " \"usePreload\": false,"
+ + " \"userParams\": [{"
+ + " \"name\": \"param\","
+ + " \"value\": \"ABCD\""
+ + " }, {"
+ + " \"name\": \"vnf_instance_name\","
+ + " \"value\": \"sample\""
+ " }"
+ " ],"
- + " \"testApi\": \"VNF_API\""
+ + " \"testApi\": \"GR_API\""
+ " }"
+ " }"
+ "}";
" ]," +
" \"requestParameters\":{" +
addTestApi()+
- " \"userParams\":[{" +
- " \"2017488_pasqualevpe0_vnf_instance_name\":\"mtnj309me6\"," +
- " \"2017488_pasqualevpe0_vnf_config_template_version\":\"17.2\"," +
- " \"pasqualevpe0_bandwidth\":\"10\"," +
- " \"2017488_pasqualevpe0_AIC_CLLI\":\"ATLMY8GA\"," +
- " \"pasqualevpe0_bandwidth_units\":\"Gbps\"" +
- " }" +
- " ]," +
+ "\"userParams\": [{"
+ + " \"name\": \"pasqualevpe0_bandwidth\","
+ + " \"value\": \"10\""
+ + " }, {"
+ + " \"name\": \"2017488_pasqualevpe0_vnf_instance_name\","
+ + " \"value\": \"mtnj309me6\""
+ + " }, {"
+ + " \"name\": \"2017488_pasqualevpe0_vnf_config_template_version\","
+ + " \"value\": \"17.2\""
+ + " }, {"
+ + " \"name\": \"2017488_pasqualevpe0_AIC_CLLI\","
+ + " \"value\": \"ATLMY8GA\""
+ + " }, {"
+ + " \"name\": \"pasqualevpe0_bandwidth_units\","
+ + " \"value\": \"Gbps\""
+ + " }"
+ + " ]," +
" \"usePreload\":true" +
" }" +
" }" +
+ " \"tenantId\": \"092eb9e8e4b7412e8787dd091bc58e86\""
+ " },"
+ " \"requestInfo\": {"
+ + " \"productFamilyId\":\"e433710f-9217-458d-a79d-1c7aff376d89\","
+ " \"source\": \"VID\","
+ " \"suppressRollback\": false,"
+ " \"requestorId\": \""+requestorId+"\""
+ " ],"
+ " \"requestParameters\": {"
+ " \"userParams\": [],"
- + " \"testApi\": \"VNF_API\""
+ + " \"testApi\": \"GR_API\""
+ " }"
+ " }"
+ "}";
"\"modelType\":\"vnf\"," +
"\"modelVersion\":\"4.0\"}," +
"\"requestParameters\":{" +
- "\"testApi\": \"VNF_API\", " +
+ "\"testApi\": \"GR_API\", " +
"\"userParams\":[]" +
"}," +
"\"relatedInstanceList\":[" +
" }" +
" ]," +
" \"requestParameters\": {" +
- " \"testApi\": \"VNF_API\", " +
+ " \"testApi\": \"GR_API\", " +
" \"userParams\": []" +
" }" +
" }" +
" }," +
" \"requestParameters\": {" +
" \"userParams\": []," +
- " \"testApi\": \"VNF_API\"" +
+ " \"testApi\": \"GR_API\"" +
" }," +
" \"relatedInstanceList\": [{" +
" \"relatedInstance\": {" +
" \"requestorId\": \"us16807000\"" +
" }," +
" \"requestParameters\": {" +
- " \"testApi\": \"VNF_API\","+
+ " \"testApi\": \"GR_API\","+
" \"aLaCarte\": true" +
" }" +
" }" +
package org.onap.simulator.presetGenerator.presets.mso;
-import com.google.common.collect.ImmutableMap;
-import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
-import org.springframework.http.HttpMethod;
+import static java.util.Collections.singletonList;
+import com.google.common.collect.ImmutableMap;
import java.util.List;
import java.util.Map;
-
-import static java.util.Collections.singletonList;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
+import org.springframework.http.HttpMethod;
public class PresetMSOOrchestrationRequestsGet5GServiceInstanceAndNetwork extends BaseMSOPreset {
" \"requestParameters\": {" +
" \"subscriptionServiceType\": \"TYLER SILVIA\"," +
" \"aLaCarte\": true," +
- " \"testApi\": \"VNF_API\"" +
+ " \"testApi\": \"GR_API\"" +
" }," +
" \"project\": {" +
" \"projectName\": \"WATKINS\"" +
package org.onap.simulator.presetGenerator.presets.mso;
-import com.google.common.collect.ImmutableMap;
-import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
-import org.springframework.http.HttpMethod;
+import static java.util.Collections.singletonList;
+import com.google.common.collect.ImmutableMap;
import java.util.List;
import java.util.Map;
-
-import static java.util.Collections.singletonList;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
+import org.springframework.http.HttpMethod;
public class PresetMSOOrchestrationRequestsGetByRequestId extends BaseMSOPreset {
" \"requestParameters\": {" +
" \"subscriptionServiceType\": \"Kennedy\"," +
" \"aLaCarte\": true," +
- " \"testApi\": \"VNF_API\"" +
+ " \"testApi\": \"GR_API\"" +
" }," +
" \"project\": {" +
" \"projectName\": \"Kennedy\"" +
package org.onap.simulator.presetGenerator.presets.mso;
-import com.google.common.collect.ImmutableMap;
-import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
-import org.springframework.http.HttpMethod;
+import static java.util.Collections.singletonList;
+import com.google.common.collect.ImmutableMap;
import java.util.List;
import java.util.Map;
-
-import static java.util.Collections.singletonList;
+import org.onap.simulator.presetGenerator.presets.BasePresets.BaseMSOPreset;
+import org.springframework.http.HttpMethod;
public class PresetMSOOrchestrationRequestsGetByServiceInstanceId extends BaseMSOPreset {
" \"requestParameters\": {" +
" \"subscriptionServiceType\": \"Kennedy\"," +
" \"aLaCarte\": true," +
- " \"testApi\": \"VNF_API\"" +
+ " \"testApi\": \"GR_API\"" +
" }," +
" \"project\": {" +
" \"projectName\": \"Kennedy\"" +
" \"lcpCloudRegionId\":\"olson5b\"" +
" }," +
" \"requestParameters\":{" +
- " \"testApi\":\"VNF_API\"" +
+ " \"testApi\":\"GR_API\"" +
" }," +
" \"platform\":{" +
" \"platformName\":\"AIC\"" +
final List<String> jobIds = createBulkOfMacroInstances(presets, false, bulkSize, names);
Assert.assertEquals(jobIds.size(),bulkSize);
+ waitForJobsToSuccessfullyCompleted(bulkSize, jobIds);
+ return jobIds;
+ }
+
+ public void waitForJobsToSuccessfullyCompleted(int bulkSize, List<String> jobIds) {
assertTrue(String.format("Not all services with ids: %s are in state completed after 30 sec",
jobIds.stream().collect(joining(","))),
Wait.waitFor(y-> serviceListCall().getBody().stream()
.filter(si -> jobIds.contains(si.jobId))
- .filter(si -> si.jobStatus==JobStatus.COMPLETED)
+ .filter(si -> si.jobStatus== JobStatus.COMPLETED)
.count() == bulkSize,
null, 30, 1 ));
- return jobIds;
}
protected List<JobAuditStatus> getJobMsoAuditStatusForAlaCarte(String jobUUID, String requestId, String serviceInstanceId){
FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS,
FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
- FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER,
FLAG_2002_UNLIMITED_MAX,
+ FLAG_2004_INSTANTIATION_TEMPLATES_POPUP,
+ FLAG_2006_VFM_SDNC_PRELOAD_FILES,
+ FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY,
+ FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF,
;
public boolean isActive() {
GeneralUIUtils.clickOnElementByTestId(Constants.OwningEntity.PROJECT_SELECT_TEST_ID);
}
- public void clickPreviousInstantiationButton() {
- GeneralUIUtils.clickOnElementByTestIdWithoutWait("ShowPreviousInstancesButton");
- }
-
}
static final String SERVICE_NAME = "ggghhh";
static final String SERVICE_ID = "537d3eb0-b7ab-4fe8-a438-6166ab6af49b";
static final String VNF_ID = "0eb38f69-d96b-4d5e-b8c9-3736c292f0f7";
- static final String DEFAULT_TEST_API_VALUE = "VNF_API";
+ static final String DEFAULT_TEST_API_VALUE = "GR_API";
public static final String SERVICE_INSTANCE_ID = "SERVICE_INSTANCE_ID";
public static final String A_LACARTE_FLOW_GET_ORCHESTRATION = "aLacarteFlow/get_orchestration_request_status.json";
public static final String ORCHESTRATION_REQUEST_ID = "orchestrationRequestId";
@Test(dataProvider = "msoTestApiOptions")
- private void testAddVfModule(String msoTestApiOption, String msoTestApiValue) {
+ public void testAddVfModule(String msoTestApiOption, String msoTestApiValue) {
withMsoTestApiConfiguration(msoTestApiOption, msoTestApiValue, () -> {
final String REQUEST_ID = "dbe54591-c8ed-46d3-abc7-d3a24873bddd";
final String MODEL_UUID = "d205e01d-e5da-4e68-8c52-f95cb0607959";
}
@Test
- private void testTenant() throws Exception {
+ public void testTenant() throws Exception {
ViewEditPage viewEditPage = new ViewEditPage();
User user = usersService.getUser("Emanuel_with_tenant");
relogin(user.credentials);
}
@Test(dataProvider = "msoTestApiOptions")
- private void testAddVnf(String msoTestApiOption, String msoTestApiValue) {
+ public void testAddVnf(String msoTestApiOption, String msoTestApiValue) {
withMsoTestApiConfiguration(msoTestApiOption, msoTestApiValue, () -> {
final String MODEL_UUID = MODEL;
String instanceName = new VidBasePage().generateInstanceName(Constants.ViewEdit.VNF_INSTANCE_NAME_PREFIX);
}
@Test(dataProvider = "msoTestApiOptions")
- private void requiredLineOfBussiness_confirmVnfWithNoLob(String msoTestApiOption, String msoTestApiValue) throws Exception {
+ public void requiredLineOfBussiness_confirmVnfWithNoLob(String msoTestApiOption, String msoTestApiValue) throws Exception {
withMsoTestApiConfiguration(msoTestApiOption, msoTestApiValue, () -> {
goToInstance();
String instanceName = new VidBasePage().generateInstanceName(Constants.ViewEdit.VNF_INSTANCE_NAME_PREFIX);
}
@Test
- private void emptyLobAfterReopenCreateVnfDialog() throws Exception {
+ public void emptyLobAfterReopenCreateVnfDialog() throws Exception {
final String lobToSelect = "ONAP";
goToInstance();
ViewEditPage viewEditPage = new ViewEditPage();
}
@Test(dataProvider = "msoTestApiOptions")
- private void testAddVolumeGroup(String msoTestApiOption, String msoTestApiValue) throws Exception {
+ public void testAddVolumeGroup(String msoTestApiOption, String msoTestApiValue) throws Exception {
withMsoTestApiConfiguration(msoTestApiOption, msoTestApiValue, () -> {
final String REQUEST_ID = "dbe54591-c8ed-46d3-abc7-d3a24873bdaa";
final String MODEL_UUID = "13f022c4-651e-4326-b8e1-61e9a8c7a7ad";
@DataProvider
public static Object[][] msoTestApiOptions() {
return new Object[][]{
- {"VNF_API (old)", DEFAULT_TEST_API_VALUE}
- , {"GR_API (new)", "GR_API"}
+ {"GR_API (new)", DEFAULT_TEST_API_VALUE}
+ , {"VNF_API (old)", "VNF_API"}
};
}
test.run();
} finally {
// back to default
- selectMsoTestApiOption("VNF_API (old)");
+ selectMsoTestApiOption("GR_API (new)");
}
}
}
import static vid.automation.test.infra.Features.FLAG_1908_COLLECTION_RESOURCE_NEW_INSTANTIATION_UI;
import static vid.automation.test.infra.Features.FLAG_2002_ANY_ALACARTE_BESIDES_EXCLUDED_NEW_INSTANTIATION_UI;
import static vid.automation.test.infra.Features.FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND;
-import static vid.automation.test.infra.Features.FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER;
import static vid.automation.test.infra.Features.FLAG_5G_IN_NEW_INSTANTIATION_UI;
import static vid.automation.test.infra.Features.FLAG_NETWORK_TO_ASYNC_INSTANTIATION;
import static vid.automation.test.infra.Features.FLAG_SHOW_ORCHESTRATION_TYPE;
return deployMacroDialog;
}
- @Test
- @FeatureTogglingTest(FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER)
- public void testClickPreviousInstantiationsInCreationDialog() {
- try {
- String serviceId = "2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd";
- DeployModernUIMacroDialog deployMacroDialog = getDeployModernUIMacroDialog(serviceId);
- deployMacroDialog.clickPreviousInstantiationButton();
-
- //exit form deploy dialog
- goOutFromIframe();
- //go into Instantiation Status page
- goToIframe();
-
- InstantiationStatusPage.verifyInstantiationStatusFilterValue(serviceId);
- }
- finally {
- goOutFromIframe();
- }
- }
-
private BrowseASDCPage registerSimulatorAndGoToBrowseSDC() {
SimulatorApi.registerExpectation(SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET,
"ecompportal_getSessionSlotCheckInterval.json",
.put("workflow", "" + workflowName + "")
.put("policyYN", "Y")
.put("sniroYN", "Y")
- .put("testApi", "VNF_API")
+ .put("testApi", "GR_API")
.put("vnfType", "vMobileDNS")
.putAll(workflowParams)
.build()
package vid.automation.test.test;
+import java.util.ArrayList;
import org.junit.Assert;
import org.onap.sdc.ci.tests.utilities.GeneralUIUtils;
import org.openqa.selenium.WebElement;
import vid.automation.test.Constants;
import vid.automation.test.infra.Click;
import vid.automation.test.infra.Exists;
-import vid.automation.test.infra.Get;
import vid.automation.test.infra.SelectOption;
import vid.automation.test.model.Service;
import vid.automation.test.model.ServiceModel;
import vid.automation.test.sections.ViewEditPage;
-import java.util.ArrayList;
-import java.util.List;
-
public class CreateInstanceDialogBaseTest extends VidBaseTestCase {
protected ViewEditPage viewEditPage= new ViewEditPage();
Assert.assertTrue(field + " " + Constants.REQUIRED, byclassAndText);
}
- protected void cancelPopup() {
- viewEditPage.clickCancelButtonByTestID();
- GeneralUIUtils.ultimateWait();
- }
-
-
-
- public static void AssertUnselectedOptionInMultiselectById(String multiSelectId, String unselectedOption){
- Click.byId(multiSelectId);
- WebElement element = Get.byClassAndText(Constants.MULTI_SELECT_UNSELECTED_CLASS, unselectedOption);
- Assert.assertTrue("The option "+ unselectedOption +" is already selected",element != null);
- Click.byId(multiSelectId);
- }
-
- public void validateDynamicFields(List<String> dynamicFields) {
- for (String field : dynamicFields) {
- WebElement fieldElement = GeneralUIUtils.findByText(field);
- Assert.assertNotNull("couldn't find dynamic field: " + field, fieldElement);
- }
- }
}
--- /dev/null
+package vid.automation.test.test;
+
+import static vid.automation.test.infra.ModelInfo.pasqualeVmxVpeBvService488Annotations;
+
+import com.google.common.collect.ImmutableList;
+import java.util.UUID;
+import org.jetbrains.annotations.NotNull;
+import vid.automation.test.infra.ModelInfo;
+import vid.automation.test.sections.ViewEditPage;
+
+public class ModernUITestBase extends VidBaseTestCase {
+
+ protected ViewEditPage viewEditPage = new ViewEditPage();
+
+ protected void prepareServicePreset(ModelInfo modelInfo, boolean deploy) {
+ String subscriberId = "e433710f-9217-458d-a79d-1c7aff376d89";
+
+ if (deploy) {
+ registerExpectationForServiceDeployment(
+ ImmutableList.of(
+ modelInfo,
+ pasqualeVmxVpeBvService488Annotations
+ ),
+ subscriberId, null);
+ } else {
+ registerExpectationForServiceBrowseAndDesign(ImmutableList.of(modelInfo), subscriberId);
+ }
+ }
+
+ @NotNull
+ protected String uuid() {
+ return UUID.randomUUID().toString();
+ }
+}
import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet.COMPLETE;
import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet.DEFAULT_SERVICE_INSTANCE_ID;
import static org.testng.Assert.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
import static vid.automation.test.infra.Features.FLAG_1902_VNF_GROUPING;
import static vid.automation.test.infra.Features.FLAG_1908_COLLECTION_RESOURCE_NEW_INSTANTIATION_UI;
import static vid.automation.test.infra.ModelInfo.macroSriovNoDynamicFieldsEcompNamingFalseFullModelDetailsVnfEcompNamingFalse;
import static vid.automation.test.infra.ModelInfo.macroSriovWithDynamicFieldsEcompNamingFalsePartialModelDetailsVnfEcompNamingFalse;
import static vid.automation.test.infra.ModelInfo.macroSriovWithDynamicFieldsEcompNamingTruePartialModelDetails;
-import static vid.automation.test.infra.ModelInfo.pasqualeVmxVpeBvService488Annotations;
import static vid.automation.test.infra.ModelInfo.transportWithPnfsService;
import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
import static vid.automation.test.services.SimulatorApi.registerExpectationFromPreset;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hamcrest.Matchers;
-import org.jetbrains.annotations.NotNull;
import org.onap.sdc.ci.tests.datatypes.UserCredentials;
import org.onap.sdc.ci.tests.utilities.GeneralUIUtils;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetL3NetworksByCloudRegionSpecificState;
import vid.automation.test.utils.ReadFile;
@FeatureTogglingTest(FLAG_ENABLE_WEBPACK_MODERN_UI)
-public class NewServiceInstanceTest extends CreateInstanceDialogBaseTest {
+public class NewServiceInstanceTest extends ModernUITestBase {
public static final String COMPLETED = "COMPLETED";
private static final String IN_PROGRESS = "IN_PROGRESS";
browseASDCPage.selectTenant("092eb9e8e4b7412e8787dd091bc58e86");
+
assertSetButtonDisabled(VNF_SET_BUTTON_TEST_ID);
if(isNetwork){
browseASDCPage.selectPlatform("platform");
}else {
SelectOption.selectOptionsFromMultiselectById("multi-selectPlatform", ImmutableList.of("platform"));
+ SelectOption.byTestIdAndVisibleText("TYLER SILVIA", Constants.ViewEdit.PRODUCT_FAMILY_SELECT_TESTS_ID);
+ browseASDCPage.selectProductFamily("e433710f-9217-458d-a79d-1c7aff376d89");
}
browseASDCPage.selectLineOfBusiness("ONAP");
}
}
- @NotNull
- private String uuid() {
- return UUID.randomUUID().toString();
+ public void validateDynamicFields(List<String> dynamicFields) {
+ for (String field : dynamicFields) {
+ WebElement fieldElement = GeneralUIUtils.findByText(field);
+ assertNotNull("couldn't find dynamic field: " + field, fieldElement);
+ }
}
-
private void assertNotificationAreaVisibilityBehaviourAndSetBulkSize(int size) {
WebElement webElement = Get.byId("notification-area");
Assert.assertNull(webElement, "notification area should be invisible if only 1 qty.");
Assert.assertNotNull(webElement, "notification area should be visible if more then 1 qty.");
}
- //@Step("prepare service preset")
- private void prepareServicePreset(ModelInfo modelInfo, boolean deploy) {
- String subscriberId = "e433710f-9217-458d-a79d-1c7aff376d89";
-
- if (deploy) {
- registerExpectationForServiceDeployment(
- ImmutableList.of(
- modelInfo,
- pasqualeVmxVpeBvService488Annotations
- ),
- subscriberId, null);
- } else {
- registerExpectationForServiceBrowseAndDesign(ImmutableList.of(modelInfo), subscriberId);
- }
- }
-
static class ServiceData {
ServiceData(String modelUuid, List<String> dynamicFields, IS_GENERATED_NAMING isServiceGeneratedNaming,
package vid.automation.test.test;
-import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
import org.onap.sdc.ci.tests.utilities.GeneralUIUtils;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import vid.automation.test.Constants;
import vid.automation.test.services.BulkRegistration;
import vid.automation.test.services.SimulatorApi;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
public class SearchExistingInstanceTest extends VidBaseTestCase {
public static final String serviceIdOeWirelineProjectX1 = "7e4f8130-5dee-47c4-8770-1abc5f5ded83";
}
@Test
- private void testSearchExistingInstanceByOwningEntitySingleValue() {
+ public void testSearchExistingInstanceByOwningEntitySingleValue() {
SearchExistingPage searchExistingPage = new SearchExistingPage();
SideMenu.navigateToSearchExistingPage();
searchExistingPage.searchByOwningEntity("Melissa");
--- /dev/null
+package vid.automation.test.test;
+
+import static org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetCloudOwnersByCloudRegionId.PRESET_SOME_LEGACY_REGION_TO_ATT_AIC;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet.COMPLETE;
+import static org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys.SERVICE_NAME;
+import static org.onap.vid.api.TestUtils.generateRandomAlphaNumeric;
+import static vid.automation.test.Constants.BrowseASDC.NewServicePopup.SET_BUTTON;
+import static vid.automation.test.Constants.DrawingBoard.CONTEXT_MENU_BUTTON_HEADER;
+import static vid.automation.test.Constants.DrawingBoard.CONTEXT_MENU_HEADER_EDIT_ITEM;
+import static vid.automation.test.Constants.DrawingBoard.DEPLOY_BUTTON;
+import static vid.automation.test.infra.Features.FLAG_2004_INSTANTIATION_TEMPLATES_POPUP;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
+import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET;
+import static vid.automation.test.services.SimulatorApi.registerExpectationFromPresets;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import org.onap.sdc.ci.tests.datatypes.UserCredentials;
+import org.onap.sdc.ci.tests.utilities.GeneralUIUtils;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOCreateServiceInstanceAlacarte;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOOrchestrationRequestGet;
+import org.onap.simulator.presetGenerator.presets.mso.PresetMSOServiceInstanceGen2WithNames.Keys;
+import org.onap.vid.api.AsyncInstantiationBase;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import vid.automation.test.infra.Click;
+import vid.automation.test.infra.FeatureTogglingTest;
+import vid.automation.test.infra.Get;
+import vid.automation.test.infra.Input;
+import vid.automation.test.infra.ModelInfo;
+import vid.automation.test.sections.DrawingBoardPage;
+import vid.automation.test.sections.SideMenu;
+import vid.automation.test.sections.VidBasePage;
+import vid.automation.test.services.AsyncJobsService;
+
+public class TemplateInstantiationTest extends ModernUITestBase {
+
+ private AsyncInstantiationBase asyncInstantiationBase;
+
+ @BeforeClass
+ protected void setUp() {
+ AsyncJobsService asyncJobsService = new AsyncJobsService();
+ asyncJobsService.dropAllAsyncJobs();
+ asyncInstantiationBase = new AsyncInstantiationBase();
+ asyncInstantiationBase.init();
+ UserCredentials userCredentials = getUserCredentials();
+ //login for API test (needed besides selenium test via browser)
+ asyncInstantiationBase.login(userCredentials);
+ }
+
+ @AfterClass
+ protected void tearDown() {
+ AsyncJobsService asyncJobsService = new AsyncJobsService();
+ asyncJobsService.muteAllAsyncJobs();
+ }
+
+ /*
+ In this test we create an simple aLaCarte service via api,
+ Then browse SDC -> search for same model uuid -> deploy ->
+ template popup is opened -> select the service -> click load template ->
+ drawing board is opened -> edit service instance name -> deploy ->
+ instantiation status is opened -> wait for service to completed.
+ */
+ @FeatureTogglingTest(FLAG_2004_INSTANTIATION_TEMPLATES_POPUP)
+ @Test
+ public void instantiateALaCarteServiceFromTemplateTest() {
+
+ final ModelInfo modelInfo = ModelInfo.aLaCarteServiceCreationNewUI;
+ String templateInstanceName = "template"+generateRandomAlphaNumeric(10);
+ String requestorID = getUserCredentials().getUserId();
+ String serviceRequestId = uuid();
+ String serviceInstanceId = uuid();
+
+ //prepare presets for first instantiation (template), and rest of scenario till deploy
+ prepareServicePreset(modelInfo, true);
+ registerExpectationFromPresets(
+ ImmutableList.of(
+ new PresetMSOCreateServiceInstanceAlacarte(
+ ImmutableMap.of(Keys.SERVICE_NAME, templateInstanceName),
+ serviceRequestId, serviceInstanceId,
+ requestorID, modelInfo),
+ PRESET_SOME_LEGACY_REGION_TO_ATT_AIC,
+ new PresetMSOOrchestrationRequestGet(COMPLETE, serviceRequestId)
+ ),
+ APPEND
+ );
+
+ //create service instance via API
+ final List<String> jobsIds = asyncInstantiationBase.createBulkOfInstances(false, 1,
+ ImmutableMap.of(SERVICE_NAME, templateInstanceName), "asyncInstantiation/vidRequestCreateALaCarteForTemplate.json");
+ asyncInstantiationBase.waitForJobsToSuccessfullyCompleted(1, jobsIds);
+
+ String newInstanceName = "template"+generateRandomAlphaNumeric(10);
+ String serviceRequestId2 = uuid();
+ String serviceInstanceId2 = uuid();
+
+ //load template and and edit service instance name
+ browseSdcAndClickDeploy(modelInfo);
+ selectTemplateByNameAndLoadTemplate(templateInstanceName);
+ VidBasePage.goToIframe();
+ editServiceInstanceName(newInstanceName);
+
+ //prepare presets for second service instance deploy
+ registerExpectationFromPresets(
+ ImmutableList.of(
+ new PresetMSOCreateServiceInstanceAlacarte(
+ ImmutableMap.of(Keys.SERVICE_NAME, newInstanceName),
+ serviceRequestId2, serviceInstanceId2,
+ requestorID, modelInfo),
+ PRESET_SOME_LEGACY_REGION_TO_ATT_AIC,
+ new PresetMSOOrchestrationRequestGet(COMPLETE, serviceRequestId2)
+ ),
+ CLEAR_THEN_SET
+ );
+
+ //deploy the service and wait for completion
+ Click.byTestId(DEPLOY_BUTTON);
+ VidBasePage.goToIframe();
+ new DrawingBoardPage().verifyServiceCompletedOnTime(newInstanceName, "service deployed from template");
+ }
+
+ private void browseSdcAndClickDeploy(ModelInfo modelInfo) {
+ SideMenu.navigateToBrowseASDCPage();
+ GeneralUIUtils.ultimateWait();
+ loadTemplatesPopupOnBrowseASDCPage(modelInfo.modelVersionId);
+ }
+
+ private void selectTemplateByNameAndLoadTemplate(String templateInstanceName) {
+ Click.byText(templateInstanceName);
+ Click.byTestId("LoadTemplateButton");
+ }
+
+ private void editServiceInstanceName(String newInstanceName) {
+ GeneralUIUtils.getClickableButtonBy(Get.getXpathForDataTestId(CONTEXT_MENU_BUTTON_HEADER), 60).click();
+ Click.byTestId(CONTEXT_MENU_HEADER_EDIT_ITEM);
+ GeneralUIUtils.ultimateWait();
+ Input.replaceText(newInstanceName, "instanceName");
+ Click.byTestId(SET_BUTTON);
+ }
+
+}
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
- this.uri = new JerseyUriBuilder().host(envUrI.getHost()).port(envUrI.getPort()).scheme("http").path("vid").build();
+ this.uri = new JerseyUriBuilder().host(envUrI.getHost()).port(envUrI.getPort()).scheme(envUrI.getScheme()).path("vid").build();
}
public void login() {
loadServicePopupOnBrowseASDCPage(modelVersionId);
}
- protected void loadServicePopupOnBrowseASDCPage(String modelVersionId ) {
+ protected void loadServicePopupOnBrowseASDCPage(String modelVersionId) {
+ loadServicePopupOnBrowseASDCPage(modelVersionId, "Model version");
+ }
+
+ protected void loadTemplatesPopupOnBrowseASDCPage (String modelVersionId) {
+ loadServicePopupOnBrowseASDCPage(modelVersionId, "Templates");
+ }
+
+ protected void loadServicePopupOnBrowseASDCPage(String modelVersionId, String expectedText) {
DeployModernUIMacroDialog deployMacroDialog = new DeployModernUIMacroDialog();
VidBasePage.goOutFromIframe();
deployMacroDialog.clickDeployServiceButtonByServiceUUID(modelVersionId);
deployMacroDialog.goToIframe();
GeneralUIUtils.ultimateWait();
- Wait.byText("Model version");
+ Wait.byText(expectedText);
}
public void assertSetButtonDisabled(String buttonTestId) {
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.collection.IsEmptyCollection.empty;
-import static org.testng.AssertJUnit.assertEquals;
import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
import com.google.common.collect.ImmutableMap;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
private final String crNetworkText ="NETWORK INSTANCE GROUP: l3network-id-rs804s | ROLE: RosemaProtectedOam.OAM | TYPE: Tenant_Layer_3 | # OF NETWORKS: 3";
private final String crCollectionText ="COLLECTION: collection-name | TYPE: L3-NETWORK";
private final String crInfoText = "\"requestState\": \"COMPLETE\"";
- SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss");
+ SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.US);
static final String LCP_REGION = "hvf6";
static final String CLOUD_OWNER = "AIC";
static final String TENANT = "bae71557c5bb4d5aac6743a4e5f1d054";
viewEditPage.clickCloseButton();
}
+ //this test works only if your browser run at UTC timezone
@Test
public void testTimestampOnDeactivateAndInfoServiceInstance() throws ParseException {
SimulatorApi.clearAll();
goToExistingInstanceById(serviceInstanceId);
Click.byClass("service-info");
GeneralUIUtils.ultimateWait();
- assertEquals("Timestamp isn't the finished time", getTimeatampValue(Constants.ViewEdit.DETAILS_LOG), "Tue, 24 Oct 2017 02:28:39");
+ assertThat("Timestamp isn't the finished time", getTimeatampValue(Constants.ViewEdit.DETAILS_LOG), matchesPattern("Mon, 23 Oct 2017 [0-9]{1,2}:28:39")); //timezone insensitive
viewEditPage.clickCloseButton();
viewEditPage.clickDeactivateButton();
GeneralUIUtils.ultimateWait();
"bulkSize": "3",
"aicZoneName": "NFTJSSSS-NFT1",
"owningEntityName": "WayneHolland",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"tenantName": "AIN Web Tool-15-D-testalexandria",
"modelInfo": {
"modelInvariantId": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
"tenantId" : "c85f0e80-0636-44a4-8cb2-4ec00d056e79",
"tenantName" : "Hedvika Wendelin",
"bulkSize": "1",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte": true
}
--- /dev/null
+{
+ "action": "Create",
+ "isDirty": true,
+ "vnfs": {},
+ "vrfs": {},
+ "instanceParams": [{}
+ ],
+ "validationCounter": 0,
+ "existingNames": {
+ "alacartewithvnfzvcjg": ""
+ },
+ "existingVNFCounterMap": {
+ "e9ed1da0-c078-426a-8e84-6f4e85eace59": 0
+ },
+ "existingVRFCounterMap": {},
+ "existingVnfGroupCounterMap": {},
+ "existingNetworksCounterMap": {},
+ "networks": {},
+ "vnfGroups": {},
+ "bulkSize": 1,
+ "instanceName": "SERVICE_NAME",
+ "globalSubscriberId": "e433710f-9217-458d-a79d-1c7aff376d89",
+ "subscriptionServiceType": "TYLER SILVIA",
+ "owningEntityId": "d61e6f2d-12fa-4cc2-91df-7c244011d6fc",
+ "projectName": "WATKINS",
+ "rollbackOnFailure": true,
+ "aicZoneName": null,
+ "owningEntityName": "WayneHolland",
+ "testApi": "GR_API",
+ "tenantName": null,
+ "modelInfo": {
+ "modelInvariantId": "d1068db8-b933-4919-8972-8bc1aed366c8",
+ "modelVersionId": "f3862254-8df2-4a0a-8137-0a9fe985860c",
+ "modelName": "vOCG_1804_SVC",
+ "modelVersion": "1.0",
+ "uuid": "f3862254-8df2-4a0a-8137-0a9fe985860c",
+ "modelUniqueId": "f3862254-8df2-4a0a-8137-0a9fe985860c"
+ },
+ "isALaCarte": true,
+ "name": "vOCG_1804_SVC",
+ "version": "1.0",
+ "description": "updated HEAT",
+ "category": "Emanuel",
+ "uuid": "f3862254-8df2-4a0a-8137-0a9fe985860c",
+ "invariantUuid": "d1068db8-b933-4919-8972-8bc1aed366c8",
+ "serviceType": "",
+ "serviceRole": "",
+ "vidNotions": {
+ "instantiationUI": "anyAlacarteWhichNotExcluded",
+ "modelCategory": "other",
+ "viewEditUI": "legacy",
+ "instantiationType": "ALaCarte"
+ },
+ "isEcompGeneratedNaming": true,
+ "isMultiStepDesign": false,
+ "subscriberName": "SILVIA ROBBINS"
+}
\ No newline at end of file
"tenantId" : "c85f0e80-0636-44a4-8cb2-4ec00d056e79",
"tenantName" : "Hedvika Wendelin",
"bulkSize": "BULK_SIZE",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte": true
}
"modelCustomizationName": "AIC30_CONTRAIL_BASIC 0"
},
"requestParameters": {
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"userParams": []
},
"cloudConfiguration": {
"userParams": [],
"subscriptionServiceType": "TYLER SILVIA",
"aLaCarte": true,
- "testApi": "VNF_API"
+ "testApi": "GR_API"
},
"subscriberInfo": {
"globalSubscriberId": "e433710f-9217-458d-a79d-1c7aff376d89",
{
"request": {
"requestId": "678cc766-b673-4a50-b9c5-471f68914590",
- "startTime": "Mon, 23 Oct 2017 23:28:39 GMT",
+ "startTime": "Mon, 23 Oct 2017 15:28:39 GMT",
"requestScope": "service",
"requestType": "createInstance",
"instanceReferences": {
"requestState": "COMPLETE",
"statusMessage": "Service Instance was created successfully.",
"percentProgress": 100,
- "finishTime": "Mon, 23 Oct 2017 23:28:39 GMT"
+ "finishTime": "Mon, 23 Oct 2017 15:28:39 GMT"
}
}
}
-{
- "param": "ABCD",
- "vnf_instance_name": "sample"
-}
\ No newline at end of file
+[
+ {
+ "name": "param",
+ "value": "ABCD"
+ },
+ {
+ "name": "vnf_instance_name",
+ "value": "sample"
+ }
+]
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.onap.simulator.presetGenerator.presets.aai.PresetAAIStandardQueryGet.defaultPlacement;
import static org.onap.simulator.presetGenerator.presets.aai.PresetAAIStandardQueryGet.ofL3Network;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertEquals;
+import static vid.automation.test.Constants.RegisterToSimulator.SearchForServiceInstance.GET_SUBSCRIBERS_FOR_CUSTOMER_CRAIG_ROBERTS;
import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.APPEND;
import static vid.automation.test.services.SimulatorApi.RegistrationStrategy.CLEAR_THEN_SET;
import static vid.automation.test.services.SimulatorApi.registerExpectationFromPresets;
import static vid.automation.test.utils.TestHelper.GET_SERVICE_MODELS_BY_DISTRIBUTION_STATUS;
import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetInstanceGroupsByCloudRegionRequiredMissing;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetL3NetworksByCloudRegion;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetL3NetworksByCloudRegionSpecificState;
+import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetModelsByOwningEntity;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetNetworkCollectionDetails;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetNetworkCollectionDetailsInvalidRequest;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetNetworkCollectionDetailsRequiredMissing;
" \"lastUpdaterFullName\": null,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" }, {\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_ERROR\",\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" }, {\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" }, {\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" }, {\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
" \"lastUpdaterUserId\": null,\n" +
" \"lastUpdaterFullName\": null,\n" +
" \"orchestrationType\": null,\n" +
+ " \"isInstantiationTemplateExists\": false,\n" +
" \"distributionStatus\": \"DISTRIBUTION_COMPLETE_OK\",\n" +
" \"artifacts\": null,\n" +
" \"resources\": null\n" +
assertThat(response.getBody(), jsonEquals(getResourceAsString(AAI_VNFS_FOR_CHANGE_MANAGEMENT_JSON_BY_PARAMS)));
}
+ @Test
+ public void searchServiceInstancesBySubscriber_serviceInstanceOfAnotherSubscriber_authIsFollowingFeatureToggle() {
+ String craigRobertsSubscriberId = "31739f3e-526b-11e6-beb8-9e71128cae77";
+ String aServiceOwningEntityId = "f160c875-ddd1-4ef5-84d8-d098784daa3a";
+ String currentUserAuthorizedOwningEntityId = "SILVIA ROBBINS"; // this will need to change with translateOwningEntityNameToOwningEntityId
+
+ SimulatorApi.registerExpectation(GET_SUBSCRIBERS_FOR_CUSTOMER_CRAIG_ROBERTS,
+ ImmutableMap.of(aServiceOwningEntityId, currentUserAuthorizedOwningEntityId), CLEAR_THEN_SET);
+
+ searchServicesAndAssertIsPermitted("subscriberId=" + craigRobertsSubscriberId, "4ea864f2-b946-473a-b51c-51a7c10b8391");
+ }
+
+ @Test
+ public void searchServiceInstancesByOwningEntity_serviceInstanceOfAnotherSubscriber_authIsFollowingFeatureToggle() {
+ String owningEntityName = "someOwning";
+ String owningEntityId = "SILVIA ROBBINS"; // this will need to change with translateOwningEntityNameToOwningEntityId
+
+ SimulatorApi.registerExpectationFromPreset(new PresetAAIGetModelsByOwningEntity(owningEntityName, owningEntityId, "fakeSubscriberId"), CLEAR_THEN_SET);
+
+ searchServicesAndAssertIsPermitted("owningEntity=" + owningEntityName, "af9d52f9-13b2-4657-a198-463677f82dc0");
+ }
+
+ private void searchServicesAndAssertIsPermitted(String queryParams, String aServiceInstanceId) {
+ boolean expectedPermission = Features.FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY.isActive();
+
+ SimulatorApi.registerExpectationFromPreset(new PresetAAIGetSubscribersGet(), APPEND);
+
+ JsonNode serviceInstancesResult = restTemplate
+ .getForObject(uri + "/search_service_instances?" + queryParams, JsonNode.class);
+
+ assertThat(serviceInstancesResult.path("service-instances").isArray(), is(true));
+
+ ArrayNode servicesArray = ((ArrayNode) serviceInstancesResult.path("service-instances"));
+
+ JsonNode aServiceResult = Streams.fromIterator(servicesArray.iterator())
+ .filter(it -> it.path("serviceInstanceId").asText().equals(aServiceInstanceId))
+ .findAny()
+ .orElseThrow(() -> new AssertionError("could not find serviceInstanceId=" + aServiceInstanceId));
+
+ assertThat(aServiceResult.toString(),
+ aServiceResult.path("isPermitted").booleanValue(), is(expectedPermission));
+ }
+
private void assertResponse(Object expected, String response) {
assertResponse(Configuration.empty(), expected, response);
}
import static vid.automation.test.services.SimulatorApi.retrieveRecordedRequests;
import com.fasterxml.jackson.databind.JsonNode;
-
import java.lang.reflect.Method;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Random;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.onap.simulator.presetGenerator.presets.aai.PresetAAIGetSubscribersGet;
import org.onap.vid.api.BaseApiTest;
+import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
}
private JsonNode getCheckerResults (String logtype, String logLines){
+
+ final int MAX_RETRIES = 3;
+
Map<String, String> params = new HashMap<>();
params.put("format", "raw");
params.put("type", logtype);
params.put("component", "vid");
params.put("data", logLines);
- return restTemplate.postForObject(logChecker, params, JsonNode.class);
+ for (int i=0; i< MAX_RETRIES; i++) {
+ try {
+ return restTemplate.postForObject(logChecker, params, JsonNode.class);
+ } catch (RestClientException exception) { //retry for cases that logchecker is not available immediately
+ logger.error("Failed to call to logChecker try: " + i, exception);
+ if (i<(MAX_RETRIES-1)) { //no need to sleep on last retry
+ try {
+ Thread.sleep((new Random().nextInt(2000) + 1000)); //random sleep between 1-3 seconds
+ } catch (InterruptedException e) {
+ ExceptionUtils.rethrow(e);
+ }
+ }
+ }
+ }
+ throw new AssertionError("failed to call to logChecker after max retries: "+MAX_RETRIES);
}
}
"modelType": "service",
"modelVersion": "1.0"
},
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"action": "Delete"
}
"modelVersion": "1.0"
},
- "testApi": "VNF_API"
+ "testApi": "GR_API"
}
"instanceName": "SERVICE_INSTANCE_NAME",
"owningEntityName": null,
"rollbackOnFailure": false,
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte": true,
"vidNotions": {
"instantiationUI": "serviceWithVnfGrouping",
"modelType": "service",
"modelVersion": "1.0"
},
- "testApi": "VNF_API"
+ "testApi": "GR_API"
}
"subscriberName": "SILVIA ROBBINS",
"owningEntityName": "WayneHolland",
"rollbackOnFailure": true,
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte": true,
"isDirty":true,
"action": "Create"
"modelVersion": "1.0"
},
- "testApi": "VNF_API"
+ "testApi": "GR_API"
}
"subscriptionServiceType": "service-instance-type",
"tenantId": null,
"tenantName": null,
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"validationCounter": 0,
"vnfGroups": {
"VNF_GROUP1_INSTANCE_ID": {
--- /dev/null
+{
+ "vnfs": {
+ "2017-488_PASQUALE-vPE 0": {
+ "action": "Create",
+ "rollbackOnFailure": "true",
+ "vfModules": {
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
+ "instanceName": "mimazepubi",
+ "rollbackOnFailure": "false",
+ "sdncPreLoad": false,
+ "instanceParams": [
+ {}
+ ],
+ "modelInfo": {
+ "modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
+ "modelVersionId": "f8360508-3f17-4414-a2ed-6bc71161e8db",
+ "modelName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
+ "modelVersion": "5",
+ "modelCustomizationId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
+ "modelUniqueId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
+ "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
+ "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db"
+ },
+ "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
+ "isMissingData": false
+ }
+ },
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
+ "instanceName": "puwesovabe",
+ "volumeGroupName": "puwesovabe_vol",
+ "rollbackOnFailure": "true",
+ "sdncPreLoad": true,
+ "instanceParams": [
+ {
+ "pasqualevpe0_bandwidth": "10",
+ "2017488_pasqualevpe0_vnf_instance_name": "mtnj309me6",
+ "2017488_pasqualevpe0_vnf_config_template_version": "17.2",
+ "2017488_pasqualevpe0_AIC_CLLI": "ATLMY8GA",
+ "pasqualevpe0_bandwidth_units": "Gbps"
+ }
+ ],
+ "modelInfo": {
+ "modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
+ "modelVersionId": "25284168-24bb-4698-8cb4-3f509146eca5",
+ "modelName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+ "modelVersion": "6",
+ "modelCustomizationId": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
+ "modelUniqueId": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
+ "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+ "uuid": "25284168-24bb-4698-8cb4-3f509146eca5"
+ },
+ "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
+ "isMissingData": false
+ }
+ },
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
+ "instanceName": "bnmgtrx",
+ "volumeGroupName": "",
+ "rollbackOnFailure": "false",
+ "sdncPreLoad": false,
+ "instanceParams": [
+ {}
+ ],
+ "modelInfo": {
+ "modelInvariantId": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
+ "modelVersionId": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
+ "modelName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
+ "modelVersion": "6",
+ "modelCustomizationId": "3cd946bb-50e0-40d8-96d3-c9023520b557",
+ "modelUniqueId": "3cd946bb-50e0-40d8-96d3-c9023520b557",
+ "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
+ "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a"
+ },
+ "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
+ "isMissingData": false
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
},
"type": "VL",
"instanceName" : "NetInstance",
- "modelCustomizationName": "ExtVL 0",
- "isFailed": true
+ "modelCustomizationName": "ExtVL 0"
}
},
"vnfs": {
"bulkSize": 1,
"rollbackOnFailure": "false",
"isALaCarte": true,
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"instanceId": "INSTANCE_ID",
"action": "None",
"trackById": "TRACK_BY_ID",
"subscriptionServiceType": "TYLER SILVIA",
"tenantId": "c85f0e80-0636-44a4-8cb2-4ec00d056e79",
"tenantName": "Hedvika Wendelin",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"trackById": "TRACK_BY_ID",
"vnfGroups": {
},
"existingNetworksCounterMap": {
},
"existingVNFCounterMap": {
- "024a417d-ca46-40bf-95ce-809c6a269011": 1
+ "024a417d-ca46-40bf-95ce-809c6a269011": 2
},
"existingVnfGroupCounterMap": {
},
}
],
"isMissingData": false,
- "lcpCloudRegionId": "hvf6",
"modelInfo": {
"modelCustomizationId": "4d0818cf-eaa9-4a3f-89c2-639953089e14",
"modelCustomizationName": "VprobeNcVnf..FE_base_module..module-0",
},
"rollbackOnFailure": true,
"sdncPreLoad": null,
- "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
"uuid": "c5b26cc1-a66f-4b69-aa23-6abc7c647c88"
}
}
}
+ },
+ "vProbe_NC_VNF 0_1": {
+ "modelInfo": {
+ "modelCustomizationName": "vProbe_NC_VNF 0",
+ "modelCustomizationId": "024a417d-ca46-40bf-95ce-809c6a269011",
+ "modelInvariantId": "a6a96924-b9c5-4c85-ae18-cbfca848095e",
+ "modelVersionId": "21ae311e-432f-4c54-b855-446d0b8ded72",
+ "modelName": "vProbe_NC_VNF",
+ "modelType": "vnf",
+ "modelVersion": "1.0"
+ },
+ "productFamilyId": "e433710f-9217-458d-a79d-1c7aff376d89",
+ "instanceName": "hvf6arlba008",
+ "vnfStoreKey": "vProbe_NC_VNF 0_1",
+ "action": "Create",
+ "platformName": "xxx1",
+ "lcpCloudRegionId": "hvf6",
+ "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
+ "instanceParams": [
+ {}
+ ],
+ "rollbackOnFailure": true,
+ "instanceId": null,
+ "vfModules": {
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0": {
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0ahubg": {
+ "modelInfo": {
+ "modelCustomizationName": "VprobeNcVnf..FE_base_module..module-0",
+ "modelCustomizationId": "4d0818cf-eaa9-4a3f-89c2-639953089e14",
+ "modelInvariantId": "29b6fa3c-aeb3-4103-b3f7-6f98e097b005",
+ "modelVersionId": "c5b26cc1-a66f-4b69-aa23-6abc7c647c88",
+ "modelName": "VprobeNcVnf..FE_base_module..module-0",
+ "modelType": "vfModule",
+ "modelVersion": "1"
+ },
+ "instanceName": "hvf6arlba007_lba_Base_02",
+ "action": "Create",
+ "lcpCloudRegionId": "hvf6",
+ "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
+ "instanceParams": [
+ {}
+ ],
+ "rollbackOnFailure": true,
+ "trackById": "ea2879a6-10bc-4697-90d7-7bc3e71da0fd",
+ "isFailed": false
+ }
+ },
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1": {
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1yprvi": {
+ "modelInfo": {
+ "modelCustomizationName": "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
+ "modelCustomizationId": "9b99d340-a80b-45ef-9ff1-993fa3e4c001",
+ "modelInvariantId": "1bcc4824-6c1a-4b51-af7c-076b7fc14d05",
+ "modelVersionId": "c09e4530-8fd8-418f-9483-2f57ce927b05",
+ "modelName": "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
+ "modelType": "vfModule",
+ "modelVersion": "1"
+ },
+ "instanceName": "my_hvf6arlba007_lba_dj_02",
+ "action": "Create",
+ "lcpCloudRegionId": "hvf6",
+ "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
+ "instanceParams": [
+ {}
+ ],
+ "rollbackOnFailure": true,
+ "trackById": "b134410e-3bc0-478e-883e-1b6bdf8a28df",
+ "isFailed": false,
+ "volumeGroupName": "my_special_hvf6arlba007_lba_dj_01_vol",
+ "sdncPreLoad": true
+ }
+ }
+ },
+ "trackById": "1d2848a0-3573-4d29-b3dd-60bb263260ea",
+ "isFailed": false,
+ "statusMessage": null,
+ "position": null,
+ "lineOfBusiness": "zzz1"
}
},
"vrfs": {
"testApi": "GR_API",
"trackById": "36601560-f8e3-4020-bdef-3e4709c51e84",
"existingVNFCounterMap": {
- "024a417d-ca46-40bf-95ce-809c6a269011": 1
+ "024a417d-ca46-40bf-95ce-809c6a269011": 2
},
"existingVRFCounterMap": {},
"existingVnfGroupCounterMap": {},
},
"instanceName": "hvf6arlba007_lba_Base_01",
"action": "Create",
+ "instanceParams": [
+ {}
+ ],
+ "rollbackOnFailure": true,
+ "trackById": "ea2879a6-10bc-4697-90d7-7bc3e71da0fd",
+ "isFailed": false
+ }
+ },
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1": {
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1yprvi": {
+ "modelInfo": {
+ "modelCustomizationName": "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
+ "modelCustomizationId": "9b99d340-a80b-45ef-9ff1-993fa3e4c001",
+ "modelInvariantId": "1bcc4824-6c1a-4b51-af7c-076b7fc14d05",
+ "modelVersionId": "c09e4530-8fd8-418f-9483-2f57ce927b05",
+ "modelName": "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
+ "modelType": "vfModule",
+ "modelVersion": "1"
+ },
+ "instanceName": "my_hvf6arlba007_lba_dj_01",
+ "action": "Create",
+ "lcpCloudRegionId": "hvf6",
+ "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
+ "instanceParams": [
+ {}
+ ],
+ "rollbackOnFailure": true,
+ "trackById": "b134410e-3bc0-478e-883e-1b6bdf8a28df",
+ "isFailed": false,
+ "volumeGroupName": "my_special_hvf6arlba007_lba_dj_01_vol",
+ "sdncPreLoad": true
+ }
+ }
+ },
+ "trackById": "1d2848a0-3573-4d29-b3dd-60bb263260ea",
+ "isFailed": false,
+ "statusMessage": null,
+ "position": null,
+ "lineOfBusiness": "zzz1"
+ },
+ "vProbe_NC_VNF 0_1": {
+ "modelInfo": {
+ "modelCustomizationName": "vProbe_NC_VNF 0",
+ "modelCustomizationId": "024a417d-ca46-40bf-95ce-809c6a269011",
+ "modelInvariantId": "a6a96924-b9c5-4c85-ae18-cbfca848095e",
+ "modelVersionId": "21ae311e-432f-4c54-b855-446d0b8ded72",
+ "modelName": "vProbe_NC_VNF",
+ "modelType": "vnf",
+ "modelVersion": "1.0"
+ },
+ "productFamilyId": "e433710f-9217-458d-a79d-1c7aff376d89",
+ "instanceName": "hvf6arlba008",
+ "action": "Create",
+ "platformName": "xxx1",
+ "lcpCloudRegionId": "hvf6",
+ "tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
+ "instanceParams": [
+ {}
+ ],
+ "rollbackOnFailure": true,
+ "instanceId": null,
+ "vfModules": {
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0": {
+ "vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0ahubg": {
+ "modelInfo": {
+ "modelCustomizationName": "VprobeNcVnf..FE_base_module..module-0",
+ "modelCustomizationId": "4d0818cf-eaa9-4a3f-89c2-639953089e14",
+ "modelInvariantId": "29b6fa3c-aeb3-4103-b3f7-6f98e097b005",
+ "modelVersionId": "c5b26cc1-a66f-4b69-aa23-6abc7c647c88",
+ "modelName": "VprobeNcVnf..FE_base_module..module-0",
+ "modelType": "vfModule",
+ "modelVersion": "1"
+ },
+ "instanceName": "hvf6arlba007_lba_Base_02",
+ "action": "Create",
"lcpCloudRegionId": "hvf6",
"tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
"instanceParams": [
"modelType": "vfModule",
"modelVersion": "1"
},
- "instanceName": "my_hvf6arlba007_lba_dj_01",
+ "instanceName": "my_hvf6arlba007_lba_dj_02",
"action": "Create",
"lcpCloudRegionId": "hvf6",
"tenantId": "4914ab0ab3a743e58f0eefdacc1dde77",
"tenantId" : "c85f0e80-0636-44a4-8cb2-4ec00d056e79",
"tenantName" : "Hedvika Wendelin",
"bulkSize": "1",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte": true
}
"tenantId" : "c85f0e80-0636-44a4-8cb2-4ec00d056e79",
"tenantName" : "Hedvika Wendelin",
"bulkSize": "1",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte": true
}
},
"orchStatus": "Active",
"modelInavariantId": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "testApi": "VNF_API"
+ "testApi": "GR_API"
}
"isALaCarte": true,
"orchStatus": "Active",
"modelInavariantId": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "testApi": "VNF_API"
+ "testApi": "GR_API"
}
\ No newline at end of file
"requestorId": "16807000"
},
"requestParameters": {
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"aLaCarte": false
}
}
"aicZoneName":null,
"projectName":null,
"rollbackOnFailure":null,
- "isALaCarte":false,
+ "isALaCarte":true,
"modelInfo":{
"modelInvariantId":"d27e42cf-087e-4d31-88ac-6c4b7585f800",
"modelVersionId": "6e59c5de-f052-46fa-aa7e-2fca9d674c44",
"rollbackOnFailure": true,
"aicZoneName": null,
"owningEntityName": "WayneHolland",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"modelInfo": {
"modelInvariantId": "dfc2c44c-2429-44ca-ae26-1e6dc1f207fb",
"modelVersionId": "f028b2e2-7080-4b13-91b2-94944d4c42d8",
});
});
- it(`VFModule a-la-carte`, () => {
- var timeBomb = new Date('12/09/2018');
- if (new Date() < timeBomb) {
- return;
- }
+ it(`Add ALaCarte VfModule Without LcpRegion Tenant Id And Legacy`, () => {
+ addAlacarteVfmoduleByFlag(true, 'redux-a-la-carte-no-lcp-tenant.json');
+ });
+
+ it(`Add ALaCarte VfModule With LcpRegion Tenant Id And Legacy`, () => {
+ addAlacarteVfmoduleByFlag(false, 'redux-a-la-carte.json');
+ });
+
+ function addAlacarteVfmoduleByFlag (flag: boolean, expectedJsonFile: string) {
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/emptyServiceRedux.json').then((res) => {
cy.setTestApiParamToGR();
res.service.serviceHierarchy['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].service.vidNotions.instantiationType = 'ALaCarte';
res.service.serviceHierarchy['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].service.inputs = null;
+ res.global['flags'] = { 'FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF' : flag };
cy.setReduxState(<any>res);
cy.openIframe('app/ui/#/servicePlanning?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd');
'2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2',
];
- cy.addALaCarteVfModule(vnfName, vfModulesNames[0], 'mimazepubi', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, false)
+ cy.addALaCarteVfModule(vnfName, vfModulesNames[0], 'mimazepubi', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, false, flag)
+ .then(() => {
+ cy.addALaCarteVfModule(vnfName, vfModulesNames[1], 'puwesovabe', 'AAIAIC25', 'my region', 'USP-SIP-IC-24335-T-01', true, true, false, flag)
.then(() => {
- cy.addALaCarteVfModule(vnfName, vfModulesNames[1], 'puwesovabe', 'AAIAIC25', 'my region', 'USP-SIP-IC-24335-T-01', true, true, false)
- .then(() => {
- cy.addALaCarteVfModule(vnfName, vfModulesNames[2], 'bnmgtrx', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, true)
- .then(() => {
- cy.getReduxState().then((state) => {
- const vfModules = state.service.serviceInstance['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].vnfs[vnfName].vfModules;
- cy.readFile('../vid-automation/src/test/resources/a-la-carte/redux-a-la-carte.json').then((file) => {
- for (let vfModulesName of vfModulesNames) {
- const vfModule = vfModules[vfModulesName];
- let vfModuleObject = vfModule[Object.keys(vfModule)[0]];
- file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName].action = "Create";
- cy.deepCompare(vfModuleObject, file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName]);
- }
- });
- });
- });
+ cy.addALaCarteVfModule(vnfName, vfModulesNames[2], 'bnmgtrx', 'hvf6', '', 'AINWebTool-15-D-iftach', false, false, true, flag)
+ .then(() => {
+ cy.getReduxState().then((state) => {
+ const vfModules = state.service.serviceInstance['2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd'].vnfs[vnfName].vfModules;
+ cy.readFile('../vid-automation/src/test/resources/a-la-carte/' + expectedJsonFile).then((file) => {
+ for (let vfModulesName of vfModulesNames) {
+ const vfModule = vfModules[vfModulesName];
+ let vfModuleObject = vfModule[Object.keys(vfModule)[0]];
+ file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName].action = "Create";
+ cy.deepCompare(vfModuleObject, file.vnfs[vnfName].vfModules[vfModulesName][vfModulesName]);
+ }
+ });
});
+ });
});
+ });
});
});
});
- });
-
+ };
function changeServiceEcompNamingToTrue(obj: ServiceModel) {
obj.service.serviceEcompNaming = "true";
.get('.error').contains(INSTANCE_NAME_NOT_MANDATORY_MESSAGE);
}
-
-
-
});
});
});
- it(`browse sdc should open instantiation template modal if service hasTemplate is true`, function () {
+ it(`browse sdc should open instantiation template modal if service isInstantiationTemplateExists is true`, function () {
const SERVICE_MODEL_ID: string = '74fa72dd-012b-49c3-800d-06b12bcaf1a0';
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/bug616888/list-services.json').then((res) => {
- res.services = res.services.map((service: { uuid: string, hasTemplate: boolean }) => {
+ res.services = res.services.map((service: { uuid: string, isInstantiationTemplateExists: boolean }) => {
if (service.uuid === SERVICE_MODEL_ID) {
- service.hasTemplate = true;
+ service.isInstantiationTemplateExists = true;
}
return service;
});
});
});
+ it(`browse sdc open create new service instance flow`, function () {
+ const MACRO_FOR_NEW_FLOW_ID: string = '745d1bf1-9ed1-413f-8111-f1e984ad63fb';
+
+ cy.initGetAAISubDetails();
+
+ cy.readFile('cypress/support/jsonBuilders/mocks/jsons/aaiGetModelsByServiceType.json').then((res) => {
+ jsonBuilderAndMock.basicJson(res,
+ Cypress.config('baseUrl') + '/aai_get_models_by_service_type/**',
+ 200,
+ 0,
+ 'aaiGetModelByServiceType');
+ });
+
+ cy.readFile('cypress/support/jsonBuilders/mocks/jsons/bug616888/Dror_service1806_Macro1.json').then((res) => {
+ jsonBuilderAndMock.basicJson(res,
+ Cypress.config('baseUrl') + '/rest/models/services/' + MACRO_FOR_NEW_FLOW_ID,
+ 200,
+ 0,
+ 'MACRO_FOR_NEW_FLOW');
+ });
+
+ cy.get('span').contains('Create New Service Instance').click({force: true})
+ .selectDropdownOptionByText('subscriberName', 'SILVIA ROBBINS');
+ cy.get('button').contains('Submit').click({force: true});
+ cy.selectDropdownOptionByText('serviceType', 'TYLER SILVIA');
+ cy.get('button').contains('Submit').click({force: true});
+ cy.wait("@aaiGetModelByServiceType").then(() => {
+ cy.getElementByDataTestsId('deploy-' + MACRO_FOR_NEW_FLOW_ID).click({force: true});
+ cy.get('button').contains('Deploy').eq(0).click({force: true});
+ cy.get('iframe').then(function ($iframe) {
+ expect($iframe.attr('src')).to.contain(`app/ui/#/servicePopup?serviceModelId=74fa72dd-012b-49c3-800d-06b12bcaf1a0`);
+ });
+ });
+
+ cy.visit("welcome.htm"); //relaod page to not break the following tests
+
+ });
+
+
it(`browse sdc of service without instantiationType open aLaCarte popup`, function () {
const VERY_OLD_SERVICE_UUID: string = "09c476c7-91ae-44b8-a731-04d8d8fa3695";
const TEST_MOCKS_PATH = "cypress/support/jsonBuilders/mocks/jsons/bug_aLaCarteServiceWrongPopup/";
cy.drawingBoardTreeClickOnContextMenuOptionByName('Remove');
cy.get('.title').contains('Remove VNF');
- cy.get('.sdc-button').contains('Remove VNF').click();
+ cy.get('.custom-button').contains('Remove VNF').click();
// assert vfModules are disabled after remove parent vnf
cy.get('.tree-node-disabled div[data-tests-id="node-2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1"]')
.should('be.visible');
"supplementaryFile_hidden_content": "{\r\n \"name\": \"a\",\r\n \"value\": \"32\"\r\n}",
"supplementaryFileContent": {
"name": "a",
- "value": "32"
+ "value": "32"
},
"supplementaryFileName": "sample.json",
"instanceParams": [
it(`Given a stored template - when click "deploy" - then a coherent request should be sent upon deploy`, () => {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
// Then...
cy.getElementByDataTestsId("node-vProbe_NC_VNF 0").should('be.visible');
it('Given a template - User can remove existing VNF', () => {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+ removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
removeVNFWithVFModules('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0');
cy.getDrawingBoardDeployBtn().click();
});
it('Given a template - User can add new VNF', () => {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
// add new node
addNewNode('node-vProbe_NC_VNF 0-add-btn')
.fillVnfPopup()
.getDrawingBoardDeployBtn().click()
.wait('@expectedPostAsyncInstantiation').then(xhr => {
- const vnfRequest = bodyOf(xhr).vnfs['vProbe_NC_VNF 0_1'];
-
- expect(vnfRequest.action).equals("Create");
- expect(vnfRequest.rollbackOnFailure).equals("true");
- expect(vnfRequest.originalName).equals("vProbe_NC_VNF 0");
- expect(vnfRequest.productFamilyId).equals("a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
- expect(vnfRequest.lcpCloudRegionId).equals("hvf6");
- expect(vnfRequest.lineOfBusiness).equals("zzz1");
- expect(vnfRequest.platformName).equals("xxx1");
- expect(vnfRequest.tenantId).equals("229bcdc6eaeb4ca59d55221141d01f8e");
+ const vnfRequest = bodyOf(xhr).vnfs['vProbe_NC_VNF 0_2'];
+
+ expect(vnfRequest.action).equals("Create");
+ expect(vnfRequest.rollbackOnFailure).equals("true");
+ expect(vnfRequest.originalName).equals("vProbe_NC_VNF 0");
+ expect(vnfRequest.productFamilyId).equals("a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb");
+ expect(vnfRequest.lcpCloudRegionId).equals("hvf6");
+ expect(vnfRequest.lineOfBusiness).equals("zzz1");
+ expect(vnfRequest.platformName).equals("xxx1");
+ expect(vnfRequest.tenantId).equals("229bcdc6eaeb4ca59d55221141d01f8e");
+
+
+ // check instance name not change if empty
+ cy.editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
+ .clearInput('instanceName');
+ cy.getElementByDataTestsId('form-set').click({force: true}).then((done) => {
+ cy.editNode('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 0)
+ .getElementByDataTestsId('instanceName').should('be.empty')
+ });
});
});
it('Given a template - User can Duplicate VNF', () => {
const numberOfDuplicate: number = 4;
- loadDrawingBoardWithRecreateMode();
- nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+ cy.nodeAction('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0', 'Duplicate')
.getElementByDataTestsId('duplicate-amount-vfmodules').select(numberOfDuplicate.toString())
.getTagElementContainsText('button', 'Duplicate').click()
.getDrawingBoardDeployBtn().click()
.wait('@expectedPostAsyncInstantiation').then(xhr => {
- expect(Object.keys(bodyOf(xhr).vnfs).length).equals(numberOfDuplicate + 1);
+ expect(Object.keys(bodyOf(xhr).vnfs).length).equals(numberOfDuplicate + 2);
});
});
it('Given a stored template - when "edit" vnf and vfmodules are opened - then template’s details are visible as expected and deploy without changes', () => {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
// Then...
- editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
+ cy.editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0")
.getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007')
.getElementByDataTestsId("productFamily").should('contain', 'Emanuel')
.getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
.checkPlatformValue('xxx1')
.getElementByDataTestsId("cancelButton").click();
- editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
+ cy.editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0")
.getElementByDataTestsId("instanceName").should('have.value', 'hvf6arlba007_lba_Base_01')
- .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
- .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
.getElementByDataTestsId("rollback").should('contain', 'Rollback')
.getElementByDataTestsId("cancelButton").click();
- editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
+ cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1")
.getElementByDataTestsId("instanceName").should('have.value', 'my_hvf6arlba007_lba_dj_01')
.getElementByDataTestsId("volumeGroupName").should('have.value', 'my_special_hvf6arlba007_lba_dj_01_vol')
- .getElementByDataTestsId("lcpRegion").should('contain', 'hvf6')
- .getElementByDataTestsId("tenant").should('contain', 'DN5242-Nov21-T1')
.getElementByDataTestsId("rollback").should('contain', 'Rollback')
.getElementByDataTestsId("sdncPreLoad").should('have.value', 'on')
.getElementByDataTestsId("cancelButton").click();
assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
{path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
+ {path: [...vnfPath2, "vnfStoreKey"], value: "vProbe_NC_VNF 0_1"},
]);
});
it(`Given a stored template - when "edit" service is opened - then template’s details are visible as expected`, function () {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
cy.openServiceContextMenu()
.getElementByDataTestsId("context-menu-header-edit-item").click()
});
it(`Given a stored template - add one VfModule, edit its details, and deploy - deploy is added with the vfModule details`, () => {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
let newVfModuleName = "new.vfmodule.name";
let module1ModelId = "VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1";
let module1CustomizationId = `vprobe_nc_vnf0..${module1ModelId}`;
// Click target VNF on right tree
- cy.getElementByDataTestsId('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0').click();
+ cy.getElementByDataTestsId('node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0').first().click();
// Click [+] vfModule on left tree
cy.drawingBoardPressAddButtonByElementName(`node-${module1CustomizationId}`)
.click({force: true});
- editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
- cy.clearInput("instanceName");
- cy.typeToInput("instanceName", newVfModuleName);
- cy.selectDropdownOptionByText('lcpRegion', 'hvf6');
- cy.selectDropdownOptionByText('tenant', 'DN5242-Nov21-T1');
- cy.getElementByDataTestsId('form-set').click();
+ cy.editNode(`node-c09e4530-8fd8-418f-9483-2f57ce927b05-${module1CustomizationId}`, 1);
+ cy.clearInput("instanceName");
+ cy.typeToInput("instanceName", newVfModuleName);
+ cy.getElementByDataTestsId('form-set').click();
// Then...
cy.getReduxState().then((state) => {
{
instanceName: newVfModuleName,
volumeGroupName: `${newVfModuleName}_vol`,
- lcpCloudRegionId: "hvf6",
- tenantId: "4914ab0ab3a743e58f0eefdacc1dde77",
}
);
assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
{path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
+ {path: [...vnfPath2, "vnfStoreKey"], value: "vProbe_NC_VNF 0_1"},
{path: ["existingNames", newVfModuleName], value: ""},
{path: ["existingNames", `${newVfModuleName}_vol`], value: ""},
{path: latestVfModule_1Path, value: latestVfModule_1ExpectedValue},
it('Given a template - User can remove existing vfmodule', function () {
- loadDrawingBoardWithRecreateMode();
- nodeAction('node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1', 'Remove');
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+ cy.nodeAction('node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1', 'Remove');
let removed_vfModule_Path = [
...vnfPath, "vfModules",
"vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1",
assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd([
{path: [...vnfPath, "vnfStoreKey"], value: "vProbe_NC_VNF 0"}, // side-effect
+ {path: [...vnfPath2, "vnfStoreKey"], value: "vProbe_NC_VNF 0_1"},
{path: [...removed_vfModule_Path], value: undefined},
]);
});
it(`Given a stored template - edit service vnf and vfmodule ${testCase.desc} - deploy request should be ${testCase.desc}`, function () {
- loadDrawingBoardWithRecreateMode();
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
//edit service
cy.openServiceContextMenu();
cy.getElementByDataTestsId('form-set').click();
// edit vnf
- editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
+ cy.editNode("node-21ae311e-432f-4c54-b855-446d0b8ded72-vProbe_NC_VNF 0");
if (testCase.modifySomeValues) {
cy.selectPlatformValue('platform');
cy.selectDropdownOptionByText("tenant", "CESAR-100-D-spjg61909");
cy.getElementByDataTestsId('form-set').click();
//edit vf module
- editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
+ cy.editNode("node-c5b26cc1-a66f-4b69-aa23-6abc7c647c88-vprobe_nc_vnf0..VprobeNcVnf..FE_base_module..module-0");
if (testCase.modifySomeValues) {
cy.getElementByDataTestsId('sdncPreLoad').click();
}
});
- it(`Given a stored template of Network - - it is loaded`, () => {
+ it(`Given a stored template of Network - - it is loaded`, () => {
- loadDrawingBoardWithRecreateModeNetwork();
+ cy.loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup);
// Then...
cy.getElementByDataTestsId("node-SR-IOV Provider 2-1").should('be.visible');
assertThatBodyFromDeployRequestEqualsToTemplateFromBackEnd_network();
});
- it(`Given a stored template of Network - User can remove existing network`, () => {
+ it(`Given a stored template of Network - User can remove existing network`, () => {
- loadDrawingBoardWithRecreateModeNetwork();
+ cy.loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup);
- nodeAction('node-01f4c475-3f89-4f00-a2f4-39a873dba0ae-SR-IOV Provider 2-1', 'Remove');
+ cy.nodeAction('node-01f4c475-3f89-4f00-a2f4-39a873dba0ae-SR-IOV Provider 2-1', 'Remove');
let removed_network_Path = [
"networks", "SR-IOV Provider 2-1",
];
it('Given a template - User can add a new network', () => {
- loadDrawingBoardWithRecreateModeNetwork();
+ cy.loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup);
// add new node
addNewNode('node-SR-IOV Provider 2-1-add-btn')
- .fillNetworkPopup()
- .getDrawingBoardDeployBtn().click()
- .wait('@expectedPostAsyncInstantiation').then(xhr => {
+ .fillNetworkPopup()
+ .getDrawingBoardDeployBtn().click()
+ .wait('@expectedPostAsyncInstantiation').then(xhr => {
const networkRequest = bodyOf(xhr).networks['SR-IOV Provider 2-1_1'];
expect(networkRequest.action).equals("Create");
"vnfs", "vProbe_NC_VNF 0"
];
-function loadDrawingBoardWithRecreateMode() {
- loadDrawingBoardWithRecreateModeInternal(
- '../../' + templateWithVnfSetup.instanceTemplateFile,
- templateWithVnfSetup.serviceModelId,
- templateWithVnfSetup.serviceModelFile);
-}
-
-function loadDrawingBoardWithRecreateModeNetwork() {
- loadDrawingBoardWithRecreateModeInternal(
- '../../' + templateWithNetworkSetup.instanceTemplateFile,
- templateWithNetworkSetup.serviceModelId,
- templateWithNetworkSetup.serviceModelFile);
-}
-
-function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
- const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
-
- const drawingBoardAction = `RECREATE`;
- const templateTopologyEndpoint = "templateTopology";
- cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
- 'fixture:' + serviceModel)
- .as('serviceModel');
-
- cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
- 'fixture:' + instanceTemplate)
- .as('templateTopology');
-
- // When...
-
- cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
- `?jobId=${templateUuid}` +
- `&serviceModelId=${serviceModelIdToLoad}`);
-
- cy.wait('@serviceModel');
- cy.wait('@templateTopology');
-}
+const vnfPath2 = [
+ "vnfs", "vProbe_NC_VNF 0_1"
+];
-function nodeAction(dataTestId: string, action: string, index ?: number) {
- return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
- .drawingBoardTreeClickOnContextMenuOptionByName(action)
-}
-function editNode(dataTestId: string, index ?: number) {
- return nodeAction(dataTestId, 'Edit', index);
-}
function addNewNode(dataTestId: string) {
return cy.getElementByDataTestsId(dataTestId).click({force: true})
}
function removeVNFWithVFModules(dataTestId: string) {
- return nodeAction(dataTestId, 'Remove')
+ return cy.nodeAction(dataTestId, 'Remove')
.getTagElementContainsText('button', 'Remove VNF').click()
}
url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
method: 'POST',
status: 200,
- response: "[]",
+ response: true,
}).as("expectedPostAsyncInstantiation");
}
+
cy.route(Cypress.config('baseUrl') + "/getuserID", 'us16807000');
- cy.openPopupIframe('/app/ui/#/servicePopup?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd&isCreate=true&hasTemplate=true');
+ cy.openPopupIframe('/app/ui/#/servicePopup?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd&isCreate=true&isInstantiationTemplateExists=true');
});
cy.get(`#header-instantiationStatus`).contains('Instantiation Status');
cy.get(`#header-region`).contains('Region');
cy.get(`#header-tenant`).contains('Tenant');
- cy.get(`#header-aicZone`).contains('AIC Zone');
// check table body row
cy.getElementByDataTestsId(`userId-${templateJobIdFromE2EFile}`).contains('16807000');
- cy.getElementByDataTestsId(`createDate-${templateJobIdFromE2EFile}`).contains('2019-12-26 11:57:05');
+ cy.getElementByDataTestsId(`createDate-${templateJobIdFromE2EFile}`).contains(/2019-12-26 [0-9]{1,2}:57:05/); //timezone insensitive
cy.getElementByDataTestsId(`instanceName-${templateJobIdFromE2EFile}`).contains('SERVICE_NAME');
cy.getElementByDataTestsId(`instantiationStatus-${templateJobIdFromE2EFile}`).contains('IN_PROGRESS');
cy.getElementByDataTestsId(`summary-${templateJobIdFromE2EFile}`).contains('vnf: 1, vfModule: 2, volumeGroup: 1');
cy.getElementByDataTestsId(`region-${templateJobIdFromE2EFile}`).contains('hvf3 (SOMENAME)');
cy.getElementByDataTestsId(`tenant-${templateJobIdFromE2EFile}`).contains('greatTenant');
- cy.getElementByDataTestsId(`aicZone-${templateJobIdFromE2EFile}`).contains('NFTJSSSS-NFT1');
//check load button is disabled
res.vnfs["2017-388_PASQUALE-vPE 0"].action = 'Create';
res.vnfs["2017-488_PASQUALE-vPE 0"].action = 'Create';
res.networks["ExtVL 0"].action = 'Create';
+ res.networks["ExtVL 0"].isFailed = true;
res.networks["ExtVL 0"].statusMessage = 'Network instantiation failed message';
// Adding VFModule with isFailed.
cy.openIframe(`app/ui/#/servicePlanning/RETRY_EDIT?serviceModelId=${SERVICE_MODEL_ID}&subscriberId=${SUBSCRIBER_ID}&serviceType=${SERVICE_TYPE}&serviceInstanceId=${SERVICE_INSTANCE_ID}&jobId=${JOB_ID}`);
- cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').click();
+ cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').eq(0).click();
cy.get('.failed-msg').should('have.length', 5);
cy.get('.newIcon').should('have.length', 4);
// Adding VFModule with isFailed.
res.vnfs["2017-488_PASQUALE-vPE 0"].vfModules["2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0"]["2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0uvfot"].isFailed = true;
res.vnfs["2017-488_PASQUALE-vPE 0"].vfModules["2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0"]["2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0uvfot"].action = 'Create';
+ res.networks["ExtVL 0"].isFailed = true;
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/responceForFailedInstance.json').then((res) => {
jsonBuilderAndMock.basicJson(
cy.openIframe(`app/ui/#/servicePlanning/RETRY?serviceModelId=${SERVICE_MODEL_ID}&subscriberId=${SUBSCRIBER_ID}&serviceType=${SERVICE_TYPE}&serviceInstanceId=${SERVICE_INSTANCE_ID}&jobId=${JOB_ID}`);
- cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').click();
+ cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').eq(0).click();
cy.get('.failed-msg').should('have.length', 4);
cy.get('.newIcon').should('have.length', 4);
--- /dev/null
+describe('SDNC preload ', () => {
+
+ beforeEach(() => {
+ cy.clearSessionStorage();
+ cy.setTestApiParamToGR();
+ cy.initAAIMock();
+ cy.initGetAAISubDetails();
+ cy.initVidMock();
+ cy.initDrawingBoardUserPermission();
+ cy.login();
+ });
+
+ afterEach(() => {
+ cy.screenshot();
+ });
+
+ it('feature toggle is on and SDNC is checked then SDNC preload file is enable : upload success' , () => {
+ mockPreloadResult(true, 200);
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+ cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1");
+ checkUploadLinkLogic();
+
+ uploadFile().then(() => {
+ cy.get('.sdc-modal__content').should('contain', 'The pre-load file(s) have been uploaded successfully.');
+ cy.getElementByDataTestsId('button-ok').click()
+ .getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload another')
+ });
+ });
+
+ it('feature toggle is on and SDNC is checked then SDNC preload file is enable : upload fail', () => {
+ mockPreloadResult(false, 200);
+ cy.loadDrawingBoardWithRecreateMode(templateWithVnfSetup);
+
+ cy.editNode("node-c09e4530-8fd8-418f-9483-2f57ce927b05-vprobe_nc_vnf0..VprobeNcVnf..FE_Add_On_Module_vlbagent_eph..module-1");
+ checkUploadLinkLogic();
+
+ uploadFile().then(() => {
+ cy.get('.sdc-modal__content').should('contain', 'Failed to upload one or more of the files, please retry.');
+ cy.getElementByDataTestsId('button-ok').click()
+ .getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload')
+ });
+ });
+});
+
+
+let apiTestResources = '../vid-automation/src/test/resources/asyncInstantiation/';
+
+const templateWithVnfSetup = {
+ serviceModelId: '6cfeeb18-c2b0-49df-987a-da47493c8e38',
+ instanceTemplateFile: apiTestResources + 'templates__instance_template.json',
+ instanceTemplateSetWithoutModifyFile: apiTestResources + 'templates__instance_from_template__set_without_modify1.json',
+ serviceModelFile: '../support/jsonBuilders/mocks/jsons/instantiationTemplates/templates__service_model.json',
+};
+
+function mockAsyncBulkResponse() {
+ cy.server().route({
+ url: Cypress.config('baseUrl') + '/asyncInstantiation/bulk',
+ method: 'POST',
+ status: 200,
+ response: true,
+ }).as("expectedPostAsyncInstantiation");
+}
+
+function mockPreloadResult(response: boolean, status?: number) {
+ cy.server().route({
+ url: Cypress.config('baseUrl') + '/preload',
+ method: 'POST',
+ status: status ? status : 200,
+ response: response,
+ }).as("preload");
+}
+
+
+function uploadFile() {
+ // @ts-ignore
+ return new Promise((resolve) => {
+ const fileName = '../support/uploadFiles/sdncPreLoadFileExample.json';
+ cy.fixture(fileName).then(fileContent => {
+ // @ts-ignore
+ cy.get('input[type=file]').eq(0).upload({fileContent, fileName, mimeType: 'application/json'}).then(() => {
+ resolve();
+ });
+ })
+ });
+}
+
+function checkUploadLinkLogic() {
+ cy.getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload').should('not.have.class', 'disabled')
+ .getElementByDataTestsId('sdncPreLoad').click()
+ .getElementByDataTestsId('sdnc_pereload_upload_link').should('contain', 'Upload').should('have.class', 'disabled')
+ .getElementByDataTestsId('sdncPreLoad').click()
+}
res1.global.flags = {};
res1.global.flags["FLAG_2004_INSTANTIATION_TEMPLATES_POPUP"] = true;
cy.setReduxState(<any>res1);
- cy.openPopupIframe('/app/ui/#/servicePopup?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd&isCreate=true&hasTemplate=true');
+ cy.openPopupIframe('/app/ui/#/servicePopup?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd&isCreate=true&isInstantiationTemplateExists=true');
cy.getElementByDataTestsId('templateButton').should('be.visible')
});
});
});
});
- it('when open service popup should show showPrevious button', () => {
- cy.openPopupIframe('/app/ui/#/servicePopup?serviceModelId=2f80c596-27e5-4ca9-b5bb-e03a7fd4c0fd&isCreate=true');
- cy.getElementByDataTestsId('ShowPreviousInstancesButton').contains('Previous Instantiation').click();
-
- })
-
-
});
});
}
cy.readFile('../vid-automation/src/test/resources/aaiGetInstanceTopology/ServiceTreeWithMultipleChildren_serviceModel.json').then((res) => {
+ res.service.instantiationType = "A-La-Carte";
+ res.service.vidNotions.instantiationType = "ALaCarte";
jsonBuilderAndMock.basicJson(
res,
Cypress.config('baseUrl') + "/rest/models/services/6e59c5de-f052-46fa-aa7e-2fca9d674c44",
beforeEach(() => {
cy.clearSessionStorage();
- cy.setTestApiParamToVNF();
+ cy.setTestApiParamToGR();
cy.initVidMock();
cy.login();
});
}
function verifyMenuActionUpgradeDoesNotExist() {
- cy.getElementByDataTestsId('node-undefined-dc229cd8-c132-4455-8517-5c1787c18b14-menu-btn').click()
- .getElementByDataTestsId('context-menu-upgrade').should('not.exist');
+ cy.getElementByDataTestsId('node-522159d5-d6e0-4c2a-aa44-5a542a12a830-vf_vgeraldine0..VfVgeraldine..vflorence_vlc..module-1-menu-btn').click().then(() => {
+ cy.getElementByDataTestsId('context-menu-upgrade').should('not.exist');
+ });
}
function setLatestVersionMockToEmptyResponse(serviceUuid: string) {
cy.getElementByDataTestsId('node-2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1').find(`[data-tests-id='node-type-indicator']`).should('have.text', 'M');
//testing right side
- cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find(`[data-tests-id='node-type-indicator']`).should('have.text', 'VNF');
- cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').click({force: true});
+ cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find(`[data-tests-id='node-type-indicator']`).should('have.length', 3).and('have.text', 'VNFVNFVNF');
+ cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').eq(0).click({force: true});
cy.getElementByDataTestsId('node-f8360508-3f17-4414-a2ed-6bc71161e8db-2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0').eq(0).find(`[data-tests-id='node-type-indicator']`).should('have.text', 'M');
//check vnf node tree sub header
- cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find("[data-tests-id='status-property-orchStatus']").should('have.text', 'Created');
- cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find("[data-tests-id='status-property-provStatus']").should('have.text', '');
+ cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find("[data-tests-id='status-property-orchStatus']").eq(0).should('have.text', 'Created');
+ cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find("[data-tests-id='status-property-provStatus']").eq(0).should('have.text', '');
cy.getElementByDataTestsId('node-69e09f68-8b63-4cc9-b9ff-860960b5db09-2017-488_PASQUALE-vPE 0').find("[data-tests-id='status-property-inMaint']").should('not.exist');
//check vf Module node tree sub header
cy.initAAIMock();
cy.initVidMock();
cy.permissionVidMock();
- cy.setTestApiParamToVNF();
+ cy.setTestApiParamToGR();
cy.login();
});
cy.screenshot();
});
+ function updateObject(obj: any, key: string, val: any, value:any) {
+ return JSON.parse(JSON.stringify(obj)
+ .replace(new RegExp(`"${key}":"${val}"`), `"${key}":"${value}"`))
+ }
+
+ function buildReduxStateWithServiceRespone(res: any, serviceId:string, isEcompGeneratedNaming:boolean) :void {
+ res = updateObject(res, "ecomp_generated_naming", !isEcompGeneratedNaming, isEcompGeneratedNaming);
+ cy.window().then((win) => {
+ win.sessionStorage.setItem('reduxState', JSON.stringify({
+ "global": {
+ "name": null
+ },
+ "service": {
+ "serviceHierarchy": {
+ [serviceId] : res
+ },
+ "serviceInstance": {
+ [serviceId]: {
+ "modelInfo" : {
+ "modelVersionId" : serviceId
+ },
+ "existingVNFCounterMap": {},
+ "existingVnfGroupCounterMap": {},
+ "existingNetworksCounterMap": {},
+ "vnfs": {},
+ "vnfGroups": {},
+ "isEcompGeneratedNaming": isEcompGeneratedNaming,
+ "existingNames": {},
+ "vidNotions": res.service.vidNotions
+ }
+ }
+ }
+ }));
+ });
+ }
+
describe('Vnf Group model basic view', function () {
it('Vnf group open new view edit', function () {
"ServiceWithVnfGroup",
);
- cy.buildReduxStateWithServiceRespone(res, serviceId, false);
+ buildReduxStateWithServiceRespone(res, serviceId, false);
cy.openIframe('app/ui/#/servicePlanning?serviceModelId=' + serviceId);
cy.getElementByDataTestsId('node-' + groupName).find(`[data-tests-id='node-type-indicator']`).contains('G');
cy.getElementByDataTestsId('node-' + groupName).contains('' + groupName);
"rollbackOnFailure": "true",
"aicZoneName": null,
"owningEntityName": "WayneHolland",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"modelInfo": {
"modelInvariantId": "dfc2c44c-2429-44ca-ae26-1e6dc1f207fb",
"modelVersionId": "f028b2e2-7080-4b13-91b2-94944d4c42d8",
"error 500 asyncInstantiation");
cy.openIframe('app/ui/#/instantiationStatus');
- cy.get('.sdc-loader')
+ cy.get('.custom-loader')
.and('be.visible');
});
+cypress/integration/iFrames/ala-carte.e2e.ts
cypress/integration/iFrames/auditInfo.modal.e2e.ts
cypress/integration/iFrames/browse-sdc.e2e.ts
+cypress/integration/iFrames/changeManagement.e2e.ts
cypress/integration/iFrames/collectionResource.e2e.ts
+cypress/integration/iFrames/commitDialog.e2e.ts
cypress/integration/iFrames/drawingBoard.e2e.ts
+cypress/integration/iFrames/instantiation-templates.e2e.ts
+cypress/integration/iFrames/instantiation.templates.modal.e2e.ts
cypress/integration/iFrames/instantiationStatus.e2e.ts
-cypress/integration/iFrames/network.popup.e2e.ts
-cypress/integration/iFrames/permission.e2e.ts
-cypress/integration/iFrames/pnf.e2e.ts
-cypress/integration/iFrames/resume.e2e.ts
-cypress/integration/iFrames/retry.e2e.ts
-cypress/integration/iFrames/viewEdit.e2e.ts
+++ /dev/null
-#!/usr/bin/env bash
-
-. $HOME/.nvm/nvm.sh
-
-set -x
-
-CYPRESS_HOME_DIR=$1
-TESTS_GROUP_FILE_1=cypress/pipeline/group1.txt
-TESTS_GROUP_FILE=cypress/pipeline/group2.generated.txt
-
-cd ${CYPRESS_HOME_DIR}
-
-# make group2 by "negating" group1.txt
-ls -1 cypress/integration/*/*.e2e.ts | comm -3 - ${TESTS_GROUP_FILE_1} > ${TESTS_GROUP_FILE}
-
-cat ${TESTS_GROUP_FILE}
-npm run cypress:headless --max-old-space-size=4096 -- --spec=$(cat ${TESTS_GROUP_FILE} | tr '\n' ',')
--- /dev/null
+#!/usr/bin/env bash
+
+. $HOME/.nvm/nvm.sh
+
+set -x
+
+CYPRESS_HOME_DIR=$1
+REMAIN_TESTS_FILE=cypress/pipeline/remain.generated.txt
+ALL_TESTS_IN_GROUPS_FILE=cypress/pipeline/all_tests.txt
+
+cd ${CYPRESS_HOME_DIR}
+cat cypress/pipeline/group?.txt | sort > ${ALL_TESTS_IN_GROUPS_FILE}
+# make group2 by "negating" group1.txt
+ls -1 cypress/integration/*/*.e2e.ts | comm -3 - ${ALL_TESTS_IN_GROUPS_FILE} > ${REMAIN_TESTS_FILE}
+
+cat ${REMAIN_TESTS_FILE}
+npm run cypress:headless --max-old-space-size=4096 -- --spec=$(cat ${REMAIN_TESTS_FILE} | tr '\n' ',')
clearSessionStorage: typeof clearSessionStorage;
setTestApiParamToGR: typeof setTestApiParamToGR;
setTestApiParamToVNF: typeof setTestApiParamToVNF;
- buildReduxStateWithServiceRespone: typeof buildReduxStateWithServiceRespone;
}
}
});
}
-function updateObject(obj: any, key: string, val: any, value:any) {
- return JSON.parse(JSON.stringify(obj)
- .replace(new RegExp(`"${key}":"${val}"`), `"${key}":"${value}"`))
-}
-
-function buildReduxStateWithServiceRespone(res: any, serviceId:string, isEcompGeneratedNaming:boolean) :void {
- res = updateObject(res, "ecomp_generated_naming", !isEcompGeneratedNaming, isEcompGeneratedNaming);
- cy.window().then((win) => {
- win.sessionStorage.setItem('reduxState', JSON.stringify({
- "global": {
- "name": null
- },
- "service": {
- "serviceHierarchy": {
- [serviceId] : res
- },
- "serviceInstance": {
- [serviceId]: {
- "existingVNFCounterMap": {},
- "existingVnfGroupCounterMap": {},
- "existingNetworksCounterMap": {},
- "vnfs": {},
- "vnfGroups": {},
- "isEcompGeneratedNaming": isEcompGeneratedNaming,
- "existingNames": {},
- "vidNotions": res.service.vidNotions
- }
- }
- }
- }));
- });
-}
-
Cypress.Commands.add('setReduxState', setReduxState);
Cypress.Commands.add('getReduxState', getReduxState);
Cypress.Commands.add('clearSessionStorage', clearSessionStorage);
Cypress.Commands.add('setTestApiParamToGR', setTestApiParamToGR);
Cypress.Commands.add('setTestApiParamToVNF',setTestApiParamToVNF);
-Cypress.Commands.add('buildReduxStateWithServiceRespone', buildReduxStateWithServiceRespone);
// Import commands.js using ES2015 syntax:
import './commands';
+import 'cypress-file-upload';
import './steps/login.step';
import './steps/fill.service.popup.step';
import './steps/fill.vnf.popup.step';
import './steps/drawingBoard/drawingBoardTree.steps';
import './steps/genericForm/genericFormAction.steps';
import './steps/genericForm/popupViewport.step';
-import './steps/drawingBoard/drawingBoardHeader.steps';
import './steps/drawingBoard/general.steps';
+import './steps/drawingBoard/drawingBoardRecreate.steps';
+import './steps/drawingBoard/drawingBoardHeader.steps';
import './steps/general/clickOutside.step';
import './steps/drawingBoard/drawingBoardComponentInfo.steps';
import './steps/genericForm/checkPopover.step';
+
// Alternatively you can use CommonJS syntax:
// require('./commands')
initActiveVPNs : typeof initActiveVPNs;
initGetAAISubDetails : typeof initGetAAISubDetails;
initAAIServices: typeof initAAIServices;
+ initGetModelByServiceType: typeof initGetModelByServiceType;
}
}
});
}
+function initGetModelByServiceType(response? : JSON) : void {
+ cy.readFile('cypress/support/jsonBuilders/mocks/jsons/aaiSubDetails.json').then((res) => {
+ cy.server()
+ .route({
+ method: 'GET',
+ status: 200,
+ url: Cypress.config('baseUrl') + "/aai_get_models_by_service_type/**",
+ response: response ? response : res
+ }).as('aai-sub-details')
+ });
+}
+
+
function initAlaCarteService(response? : JSON) : void {
cy.readFile('cypress/support/jsonBuilders/mocks/jsons/a-la-carteService.json').then((res) => {
cy.server()
Cypress.Commands.add('initActiveNetworks', initActiveNetworks);
Cypress.Commands.add('initActiveVPNs', initActiveVPNs);
Cypress.Commands.add('initAAIServices', initAAIServices);
+Cypress.Commands.add('initGetModelByServiceType', initGetModelByServiceType);
--- /dev/null
+{
+ "inventory-response-item": [
+ {
+ "service-subscription": {
+ "service-type": "TYLER SILVIA",
+ "resource-version": "1494001841964"
+ },
+ "extra-properties": {},
+ "inventory-response-items": {
+ "inventory-response-item":[
+ {
+ "model-name": "RG_11-18_vccf_srvc",
+ "service-instance": {
+ "service-instance-id": "b9769e8f-70aa-4b05-8988-64044aa63498",
+ "service-instance-name": "TestCharlie",
+ "model-invariant-id": "4af418a9-c2f5-4fae-a577-b69d6341eee8",
+ "model-version-id": "745d1bf1-9ed1-413f-8111-f1e984ad63fb",
+ "resource-version": "1494002070115"
+ },
+ "extra-properties": {
+ "extra-property": [
+ {
+ "property-name": "model-ver.model-description",
+ "property-value": "Service for vccf"
+ },
+ {
+ "property-name": "model-ver.model-version-id",
+ "property-value": "745d1bf1-9ed1-413f-8111-f1e984ad63fb"
+ },
+ {
+ "property-name": "model-ver.model-name",
+ "property-value": "RG_11-18_vccf_srvc"
+ },
+ {
+ "property-name": "model.model-type",
+ "property-value": "service"
+ },
+ {
+ "property-name": "model.model-invariant-id",
+ "property-value": "4af418a9-c2f5-4fae-a577-b69d6341eee8"
+ },
+ {
+ "property-name": "model.model-description"
+ },
+ {
+ "property-name": "model-ver.model-version",
+ "property-value": "1.0"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+}
+
+
},
"requestParameters": {
"userParams": [],
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"usePreload": false
},
"cloudConfiguration": {
"FLAG_1911_INSTANTIATION_ORDER_BUTTON_IN_ASYNC_ALACARTE": false,
"FLAG_2002_VNF_PLATFORM_MULTI_SELECT" : true,
"FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS": true,
- "FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER": true,
"FLAG_2004_INSTANTIATION_STATUS_FILTER": true,
"FLAG_2004_INSTANTIATION_TEMPLATES_POPUP" : false,
"FLAG_2002_UNLIMITED_MAX" : true,
- "FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE": true
+ "FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE": true,
+ "FLAG_2006_VFM_SDNC_PRELOAD_FILES" : true,
+ "FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF": true
}
"subscriberName":"SILVIA ROBBINS",
"owningEntityName":"WayneHolland",
"rollbackOnFailure":"true",
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"isALaCarte":true,
"action": "Create"
}
--- /dev/null
+declare namespace Cypress {
+ interface Chainable {
+ loadDrawingBoardWithRecreateMode: typeof loadDrawingBoardWithRecreateMode ,
+ loadDrawingBoardWithRecreateModeNetwork: typeof loadDrawingBoardWithRecreateModeNetwork,
+ loadDrawingBoardWithRecreateModeInternal: typeof loadDrawingBoardWithRecreateModeInternal
+ }
+}
+
+function loadDrawingBoardWithRecreateMode(templateWithVnfSetup : any) {
+ cy.loadDrawingBoardWithRecreateModeInternal(
+ '../../' + templateWithVnfSetup.instanceTemplateFile,
+ templateWithVnfSetup.serviceModelId,
+ templateWithVnfSetup.serviceModelFile);
+}
+
+function loadDrawingBoardWithRecreateModeNetwork(templateWithNetworkSetup : any) {
+ cy.loadDrawingBoardWithRecreateModeInternal(
+ '../../' + templateWithNetworkSetup.instanceTemplateFile,
+ templateWithNetworkSetup.serviceModelId,
+ templateWithNetworkSetup.serviceModelFile);
+}
+
+function loadDrawingBoardWithRecreateModeInternal(instanceTemplate: string, serviceModelIdToLoad: any, serviceModel: string) {
+ const templateUuid = "46390edd-7100-46b2-9f18-419bd24fb60b";
+
+ const drawingBoardAction = `RECREATE`;
+ const templateTopologyEndpoint = "templateTopology";
+ cy.route(`**/rest/models/services/${serviceModelIdToLoad}`,
+ 'fixture:' + serviceModel)
+ .as('serviceModel');
+
+ cy.route(`**/instantiationTemplates/${templateTopologyEndpoint}/${templateUuid}`,
+ 'fixture:' + instanceTemplate)
+ .as('templateTopology');
+
+ // When...
+
+ cy.openIframe(`app/ui/#/servicePlanning/${drawingBoardAction}` +
+ `?jobId=${templateUuid}` +
+ `&serviceModelId=${serviceModelIdToLoad}`);
+
+ cy.wait('@serviceModel');
+ cy.wait('@templateTopology');
+}
+
+
+
+
+
+Cypress.Commands.add('loadDrawingBoardWithRecreateMode', loadDrawingBoardWithRecreateMode);
+Cypress.Commands.add('loadDrawingBoardWithRecreateModeNetwork', loadDrawingBoardWithRecreateModeNetwork);
+Cypress.Commands.add('loadDrawingBoardWithRecreateModeInternal', loadDrawingBoardWithRecreateModeInternal);
declare namespace Cypress {
interface Chainable {
updateServiceShouldNotOverrideChild: typeof updateServiceShouldNotOverrideChild
- openServiceContextMenu: typeof openServiceContextMenu
+ openServiceContextMenu: typeof openServiceContextMenu,
+ drawingBoardTreeClickOnContextMenuOptionByName : typeof drawingBoardTreeClickOnContextMenuOptionByName,
+ nodeAction: typeof nodeAction,
+ editNode : typeof editNode
}
}
});
});
});
-
}
return cy.getElementByDataTestsId('openMenuBtn').click({force: true});
}
+function nodeAction(dataTestId: string, action: string, index ?: number) {
+ return cy.drawingBoardTreeOpenContextMenuByElementDataTestId(dataTestId, index)
+ .drawingBoardTreeClickOnContextMenuOptionByName(action)
+}
+
+function drawingBoardTreeClickOnContextMenuOptionByName(optionName : string) : Chainable<any> {
+ switch (optionName) {
+ case 'Duplicate':
+ return cy.getElementByDataTestsId('context-menu-duplicate').click({force : true});
+ case 'Remove':
+ return cy.getElementByDataTestsId('context-menu-remove').click({force : true});
+ case 'Edit':
+ return cy.getElementByDataTestsId('context-menu-edit').click({force : true});
+ case 'Delete':
+ return cy.getElementByDataTestsId('context-menu-delete').trigger('mouseover').click();
+ case 'Upgrade':
+ return cy.getElementByDataTestsId('context-menu-upgrade').trigger('mouseover').click();
+ case 'Undo Upgrade':
+ return cy.getElementByDataTestsId('context-menu-undoUpgrade').trigger('mouseover').click();
+ default:
+ return cy.getElementByDataTestsId('context-menu-duplicate').click({force : true});
+ }
+}
+
+function editNode(dataTestId: string, index ?: number) {
+ return cy.nodeAction(dataTestId, 'Edit', index);
+}
+
Cypress.Commands.add('updateServiceShouldNotOverrideChild', updateServiceShouldNotOverrideChild);
Cypress.Commands.add('openServiceContextMenu', openServiceContextMenu);
+Cypress.Commands.add('drawingBoardTreeClickOnContextMenuOptionByName', drawingBoardTreeClickOnContextMenuOptionByName);
+Cypress.Commands.add('nodeAction', nodeAction);
+Cypress.Commands.add('editNode', editNode);
}
function addALaCarteVfModule(vnfName: string, vfModuleName: string, instanceName: string, lcpRegion: string, legacyRegion: string,
- tenant: string, rollback: boolean, sdncPreLoad: boolean, deleteVgName: boolean): Chainable<any> {
+ tenant: string, rollback: boolean, sdncPreLoad: boolean, deleteVgName: boolean, flag: boolean): Chainable<any> {
return cy.getElementByDataTestsId('node-' + vnfName).click({force: true}).then(() => {
cy.getElementByDataTestsId('node-' + vfModuleName + '-add-btn').click({force: true}).then(() => {
cy.getElementByDataTestsId('instanceName').clear().type(instanceName, {force: true}).then(() => {
cy.getElementByDataTestsId('volumeGroupName').clear();
}
}).then(() => {
- cy.selectDropdownOptionByText('lcpRegion', lcpRegion);
- if (legacyRegion) {
- cy.typeToInput("lcpRegionText", legacyRegion);
+ if(!flag) {
+ cy.selectDropdownOptionByText('lcpRegion', lcpRegion);
+ if (legacyRegion) {
+ cy.typeToInput("lcpRegionText", legacyRegion);
+ }
+ cy.selectDropdownOptionByText('tenant', tenant);
}
- cy.selectDropdownOptionByText('tenant', tenant);
cy.selectDropdownOptionByText('rollback', String(rollback));
if (sdncPreLoad) {
cy.getElementByDataTestsId('sdncPreLoad').check();
--- /dev/null
+{
+ "comment" : "invalid file, just for upload mock file"
+}
"cypress": "3.6.1",
"typescript": "3.1.6",
"rxjs": "^6.3.3",
- "rxjs-compat": "^6.3.3"
+ "rxjs-compat": "^6.3.3",
+ "cypress-file-upload": "^3.5.3"
}
}
"private": true,
"dependencies": {
"@angular-redux/store": "9.0.0",
- "@angular/animations": "7.1.4",
+ "@angular/animations": "8.2.14",
"@angular/cdk": "7.2.2",
- "@angular/common": "7.1.4",
- "@angular/compiler": "7.1.4",
- "@angular/core": "7.1.4",
- "@angular/forms": "7.1.4",
- "@angular/http": "7.1.4",
+ "@angular/common": "8.2.14",
+ "@angular/compiler": "8.2.14",
+ "@angular/core": "8.2.14",
+ "@angular/forms": "8.2.14",
"@angular/material": "7.2.2",
- "@angular/platform-browser": "7.1.4",
- "@angular/platform-browser-dynamic": "7.1.4",
- "@angular/platform-server": "7.1.4",
- "@angular/router": "7.1.4",
+ "@angular/platform-browser": "8.2.14",
+ "@angular/platform-browser-dynamic": "8.2.14",
+ "@angular/platform-server": "8.2.14",
+ "@angular/router": "8.2.14",
"@harmowatch/ngx-redux-core": "0.2.2",
- "@nicky-lenaers/ngx-scroll-to": "^0.6.1",
+ "@nicky-lenaers/ngx-scroll-to": "3.0.1",
"@turf/turf": "5.1.6",
"@types/lodash": "4.14.121",
"angular-svg-icon": "5.0.0",
- "angular-tree-component": "8.4.0",
+ "angular-tree-component": "8.5.2",
"angular2-datatable": "0.6.0",
"angular2-multiselect-dropdown": "2.5.0",
"angular5-csv": "^0.2.10",
"moment": "^2.24.0",
"ng-multiselect-dropdown": "0.1.3",
"ng2-bootstrap-modal": "1.0.1",
+ "ng2-file-upload": "^1.4.0",
"ngx-bootstrap": "^2.0.2",
"ngx-contextmenu": "^5.1.1",
"ngx-datatable": "1.0.3",
"ngx-moment": "^2.0.0-rc.0",
"ngx-tooltip": "0.0.9",
+ "node-sass": "^4.13.0",
"npm": "^6.4.1",
"redux": "4.0.1",
"redux-observable": "^1.0.0",
"rxjs-compat": "^6.3.3",
"slnodejs": "^2.1.124",
"tslib": "1.9.x",
- "zone.js": "^0.8.26"
+ "zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-builders/jest": "7.3.1",
- "@angular-devkit/build-angular": "0.13.1",
- "@angular/cli": "7.3.1",
- "@angular/compiler-cli": "7.2.5",
- "@angular/language-service": "7.2.5",
+ "@angular-devkit/build-angular": "~0.803.21",
+ "@angular/cli": "8.3.21",
+ "@angular/compiler-cli": "8.2.14",
+ "@angular/language-service": "8.2.14",
"@babel/preset-env": "7.3.1",
"@bahmutov/add-typescript-to-cypress": "2.0.0",
"@types/chai": "4.1.7",
"@types/node": "^10.12.18",
"angular2-template-loader": "0.6.2",
"babel-jest": "24.1.0",
- "codelyzer": "4.5.0",
+ "blueimp-file-upload": "^10.7.0",
+ "codelyzer": "^5.0.1",
"cypress": "3.6.1",
+ "cypress-file-upload": "^3.5.3",
"hammerjs": "2.0.8",
"husky": "^1.3.1",
"istanbul-reports": "2.1.1",
"jest-sonar-reporter": "2.0.0",
"ngx-wallaby-jest": "0.0.1",
"npm-run-all": "^4.1.5",
- "onap-ui-angular": "5.2.4",
+ "onap-ui-angular": "5.2.7",
"onap-ui-common": "1.0.105",
"prettier": "1.16.4",
"pretty-quick": "^1.10.0",
+ "redux-observable-es6-compat": "^1.2.1",
"ts-mockito": "2.3.1",
"ts-node": "~5.0.1",
"tslint": "^5.12.0",
- "typescript": "3.1.6",
+ "typescript": "3.5.3",
"wallaby-webpack": "^3.9.11",
"webpack": "^4.28.2"
},
inherit from a parent maven module. -->
<groupId>org.onap.vid</groupId>
<artifactId>vid-webpack-master</artifactId>
- <version>6.0.0-SNAPSHOT</version>
+ <version>6.0.3-SNAPSHOT</version>
<packaging>war</packaging>
<name>VID UI</name>
<description>VID UI</description>
</goals>
<configuration>
<!-- See https://nodejs.org/en/download/ for latest node and npm (lts) versions -->
- <nodeVersion>v8.9.4</nodeVersion>
- <npmVersion>5.6.0</npmVersion>
+ <nodeVersion>v10.15.3</nodeVersion>
+ <npmVersion>6.9.0</npmVersion>
</configuration>
</execution>
import {ComponentInfoService} from "./service-planning/component-info/component-info.service";
import {NetworkStepService} from "./service-planning/objectsToTree/models/vrf/vrfModal/networkStep/network.step.service";
import {VpnStepService} from "./service-planning/objectsToTree/models/vrf/vrfModal/vpnStep/vpn.step.service";
+import {ModalModule} from "onap-ui-angular/dist/modals/modal.module";
+import {ModalService} from "../shared/components/customModal/services/modal.service";
@NgModule({
CommonModule,
SdcUiComponentsModule,
SharedModule.forRoot(),
- FeatureFlagModule.forRoot()],
+ FeatureFlagModule.forRoot(),
+ ModalModule],
providers: [
AaiService,
ObjectToTreeService,
DynamicInputsService,
InstanceTreeGenerator,
SharedTreeService,
- SdcUiServices.ModalService,
+ ModalService,
SdcUiServices.LoaderService,
CreateDynamicComponentService,
ComponentInfoService,
SearchComponent,
ComponentInfoComponent],
entryComponents: [DuplicateVnfComponent],
- exports: [AvailableModelsTreeComponent, DrawingBoardTreeComponent, DrawingBoardHeader, TreeNodeHeaderPropertiesComponent, SearchComponent]
+ exports: [AvailableModelsTreeComponent, DrawingBoardTreeComponent, DrawingBoardHeader, TreeNodeHeaderPropertiesComponent, SearchComponent, DuplicateVnfComponent]
})
export class DrawingBoardModule {
<span [attr.data-tests-id]="'numberButton'">{{node.data.getNodeCount(node, this.serviceModelId)}}</span>
</span>
<span class="icon-v" *ngIf="node?.data?.showNodeIcons(node, serviceModelId)?.vIcon">
- <svg-icon
+ <custom-icon
[mode]="'secondary'"
[name]="'maximum'">
- </svg-icon>
+ </custom-icon>
</span>
<span class="icon-plus" *ngIf="_store.getState().service.serviceInstance[serviceModelId].action !== 'Delete' && node?.data?.showNodeIcons(node, serviceModelId)?.addIcon">
<span tooltip="Add" [attr.data-tests-id]="'node-'+node.data.name+'-add-btn'" (click)="onClickAdd(node, serviceModelId)">
@Output()
highlightInstances: EventEmitter<number> = new EventEmitter<number>();
- @ViewChild('tree') tree: TreeComponent;
+ @ViewChild('tree', {static: false}) tree: TreeComponent;
nodes = [];
service = {name: ''};
this.highlightInstances.emit(node.data.modelUniqueId);
if (FeatureFlagsService.getFlagState(Features.FLAG_1906_COMPONENT_INFO, this.store)) {
const serviceHierarchy = this._store.getState().service.serviceHierarchy[this.serviceModelId];
- const model = node.data.getModel(node.data.name, node.data, serviceHierarchy);
+
+ const instanceModel = this._sharedTreeService.modelByIdentifiers(
+ serviceHierarchy, node.data.modelTypeName,
+ this._sharedTreeService.modelUniqueNameOrId(node.data), node.data.name
+ );
+
+ const model = node.data.getModel(instanceModel);
const modelInfoItems = node.data.getInfo(model, null);
const componentInfoModel :ComponentInfoModel = this._sharedTreeService.addGeneralInfoItems(modelInfoItems, node.data.componentInfoType, model, null);
ComponentInfoService.triggerComponentInfoChange.next(componentInfoModel);
let injector;
let service: AvailableModelsTreeService;
let httpMock: HttpTestingController;
+ let sharedTreeService: SharedTreeService;
beforeAll(done => (async () => {
TestBed.configureTestingModule({
injector = getTestBed();
service = injector.get(AvailableModelsTreeService);
httpMock = injector.get(HttpTestingController);
+ sharedTreeService = injector.get(SharedTreeService);
})().then(done).catch(done.fail));
describe('#shouldOpenModalDialogOnAddInstance', () => {
- let serviceHierarchy = getServiceServiceHierarchy();
test('should open popup on add instance', () => {
// add vnf should return true
"isEcompGeneratedNaming": false,
"typeName": "VRF",
"componentInfoType": "VRF",
+ "data": {
+ },
"getModel" : ()=>{
return {
min : 1
const serviceStore = {
+ "serviceHierarchy": {
+ "4117a0b6-e234-467d-b5b9-fe2f68c8b0fc": {}
+ },
"serviceInstance": {
"4117a0b6-e234-467d-b5b9-fe2f68c8b0fc": {
"action": "Create",
"physicalName": "sriovnet0",
"instanceId": "46fcb25a-e7ba-4d96-99ba-3bb6eae6aba7",
"serviceName": "LPPVPN",
- "serv§iceUUID": "VPN1271",
+ "serviceUUID": "VPN1271",
"tenantName": "ecomp_ispt",
"lcpCloudRegionId": "USA,EMEA",
"modelInfo": {
}
};
+ spyOn(sharedTreeService, 'modelByIdentifiers').and.returnValue({});
+
const serviceModelId :string = '4117a0b6-e234-467d-b5b9-fe2f68c8b0fc';
let result: boolean = service.shouldOpenVRFModal(nodes, serviceModelId, serviceStore);
});
- function getServiceServiceHierarchy() {
- return JSON.parse(JSON.stringify(
- {
- '6e59c5de-f052-46fa-aa7e-2fca9d674c44': {
- 'service': {
- 'uuid': '6e59c5de-f052-46fa-aa7e-2fca9d674c44',
- 'invariantUuid': 'e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0',
- 'name': 'ComplexService',
- 'version': '1.0',
- 'toscaModelURL': null,
- 'category': 'Emanuel',
- 'serviceType': '',
- 'serviceRole': '',
- 'description': 'ComplexService',
- 'serviceEcompNaming': 'true',
- 'instantiationType': 'Macro',
- 'inputs': {}
- },
- 'vnfs': {
- 'VF_vGeraldine 0': {
- 'uuid': 'd6557200-ecf2-4641-8094-5393ae3aae60',
- 'invariantUuid': '4160458e-f648-4b30-a176-43881ffffe9e',
- 'description': 'VSP_vGeraldine',
- 'name': 'VF_vGeraldine',
- 'version': '2.0',
- 'customizationUuid': '91415b44-753d-494c-926a-456a9172bbb9',
- 'inputs': {},
- 'commands': {},
- 'properties': {
- 'max_instances': '3',
- 'min_instances': '1',
- 'gpb2_Internal2_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-ipv6-egress_src_start_port': '0',
- 'sctp-a-ipv6-egress_rule_application': 'any',
- 'Internal2_allow_transit': 'true',
- 'sctp-b-IPv6_ethertype': 'IPv6',
- 'sctp-a-egress_rule_application': 'any',
- 'sctp-b-ingress_action': 'pass',
- 'sctp-b-ingress_rule_protocol': 'icmp',
- 'ncb2_Internal1_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-ipv6-ingress-src_start_port': '0.0',
- 'ncb1_Internal2_mac': '00:11:22:EF:AC:DF',
- 'fsb_volume_size_0': '320.0',
- 'sctp-b-egress_src_addresses': 'local',
- 'sctp-a-ipv6-ingress_ethertype': 'IPv4',
- 'sctp-a-ipv6-ingress-dst_start_port': '0',
- 'sctp-b-ipv6-ingress_rule_application': 'any',
- 'domain_name': 'default-domain',
- 'sctp-a-ingress_rule_protocol': 'icmp',
- 'sctp-b-egress-src_start_port': '0.0',
- 'sctp-a-egress_src_addresses': 'local',
- 'sctp-b-display_name': 'epc-sctp-b-ipv4v6-sec-group',
- 'sctp-a-egress-src_start_port': '0.0',
- 'sctp-a-ingress_ethertype': 'IPv4',
- 'sctp-b-ipv6-ingress-dst_end_port': '65535',
- 'sctp-b-dst_subnet_prefix_v6': '::',
- 'nf_naming': '{ecomp_generated_naming=true}',
- 'sctp-a-ipv6-ingress_src_subnet_prefix': '0.0.0.0',
- 'sctp-b-egress-dst_start_port': '0.0',
- 'ncb_flavor_name': 'nv.c20r64d1',
- 'gpb1_Internal1_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-egress_dst_subnet_prefix_len': '0.0',
- 'Internal2_net_cidr': '10.0.0.10',
- 'sctp-a-ingress-dst_start_port': '0.0',
- 'sctp-a-egress-dst_start_port': '0.0',
- 'fsb1_Internal2_mac': '00:11:22:EF:AC:DF',
- 'sctp-a-egress_ethertype': 'IPv4',
- 'vlc_st_service_mode': 'in-network-nat',
- 'sctp-a-ipv6-egress_ethertype': 'IPv4',
- 'sctp-a-egress-src_end_port': '65535.0',
- 'sctp-b-ipv6-egress_rule_application': 'any',
- 'sctp-b-egress_action': 'pass',
- 'sctp-a-ingress-src_subnet_prefix_len': '0.0',
- 'sctp-b-ipv6-ingress-src_end_port': '65535.0',
- 'sctp-b-name': 'epc-sctp-b-ipv4v6-sec-group',
- 'fsb2_Internal1_mac': '00:11:22:EF:AC:DF',
- 'sctp-a-ipv6-ingress-src_start_port': '0.0',
- 'sctp-b-ipv6-egress_ethertype': 'IPv4',
- 'Internal1_net_cidr': '10.0.0.10',
- 'sctp-a-egress_dst_subnet_prefix': '0.0.0.0',
- 'fsb_flavor_name': 'nv.c20r64d1',
- 'sctp_rule_protocol': '132',
- 'sctp-b-ipv6-ingress_src_subnet_prefix_len': '0',
- 'sctp-a-ipv6-ingress_rule_application': 'any',
- 'sctp-a-IPv6_ethertype': 'IPv6',
- 'vlc2_Internal1_mac': '00:11:22:EF:AC:DF',
- 'vlc_st_virtualization_type': 'virtual-machine',
- 'sctp-b-ingress-dst_start_port': '0.0',
- 'sctp-b-ingress-dst_end_port': '65535.0',
- 'sctp-a-ipv6-ingress-src_end_port': '65535.0',
- 'sctp-a-display_name': 'epc-sctp-a-ipv4v6-sec-group',
- 'sctp-b-ingress_rule_application': 'any',
- 'int2_sec_group_name': 'int2-sec-group',
- 'vlc_flavor_name': 'nd.c16r64d1',
- 'sctp-b-ipv6-egress_src_addresses': 'local',
- 'vlc_st_interface_type_int1': 'other1',
- 'sctp-b-egress-src_end_port': '65535.0',
- 'sctp-a-ipv6-egress-dst_start_port': '0',
- 'vlc_st_interface_type_int2': 'other2',
- 'sctp-a-ipv6-egress_rule_protocol': 'any',
- 'Internal2_shared': 'false',
- 'sctp-a-ipv6-egress_dst_subnet_prefix_len': '0',
- 'Internal2_rpf': 'disable',
- 'vlc1_Internal1_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-ipv6-egress_src_end_port': '65535',
- 'sctp-a-ipv6-egress_src_addresses': 'local',
- 'sctp-a-ingress-dst_end_port': '65535.0',
- 'sctp-a-ipv6-egress_src_end_port': '65535',
- 'Internal1_forwarding_mode': 'l2',
- 'Internal2_dhcp': 'false',
- 'sctp-a-dst_subnet_prefix_v6': '::',
- 'pxe_image_name': 'MME_PXE-Boot_16ACP04_GA.qcow2',
- 'vlc_st_interface_type_gtp': 'other0',
- 'ncb1_Internal1_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-src_subnet_prefix_v6': '::',
- 'sctp-a-egress_dst_subnet_prefix_len': '0.0',
- 'int1_sec_group_name': 'int1-sec-group',
- 'Internal1_dhcp': 'false',
- 'sctp-a-ipv6-egress_dst_end_port': '65535',
- 'Internal2_forwarding_mode': 'l2',
- 'fsb2_Internal2_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-egress_dst_subnet_prefix': '0.0.0.0',
- 'Internal1_net_cidr_len': '17',
- 'gpb2_Internal1_mac': '00:11:22:EF:AC:DF',
- 'sctp-b-ingress-src_subnet_prefix_len': '0.0',
- 'sctp-a-ingress_dst_addresses': 'local',
- 'sctp-a-egress_action': 'pass',
- 'fsb_volume_type_0': 'SF-Default-SSD',
- 'ncb2_Internal2_mac': '00:11:22:EF:AC:DF',
- 'vlc_st_interface_type_sctp_a': 'left',
- 'vlc_st_interface_type_sctp_b': 'right',
- 'sctp-a-src_subnet_prefix_v6': '::',
- 'vlc_st_version': '2',
- 'sctp-b-egress_ethertype': 'IPv4',
- 'sctp-a-ingress_rule_application': 'any',
- 'gpb1_Internal2_mac': '00:11:22:EF:AC:DF',
- 'instance_ip_family_v6': 'v6',
- 'sctp-a-ipv6-egress_src_start_port': '0',
- 'sctp-b-ingress-src_start_port': '0.0',
- 'sctp-b-ingress_dst_addresses': 'local',
- 'fsb1_Internal1_mac': '00:11:22:EF:AC:DF',
- 'vlc_st_interface_type_oam': 'management',
- 'multi_stage_design': 'false',
- 'oam_sec_group_name': 'oam-sec-group',
- 'Internal2_net_gateway': '10.0.0.10',
- 'sctp-a-ipv6-ingress-dst_end_port': '65535',
- 'sctp-b-ipv6-egress-dst_start_port': '0',
- 'Internal1_net_gateway': '10.0.0.10',
- 'sctp-b-ipv6-egress_rule_protocol': 'any',
- 'gtp_sec_group_name': 'gtp-sec-group',
- 'sctp-a-ipv6-egress_dst_subnet_prefix': '0.0.0.0',
- 'sctp-b-ipv6-egress_dst_subnet_prefix_len': '0',
- 'sctp-a-ipv6-ingress_dst_addresses': 'local',
- 'sctp-a-egress_rule_protocol': 'icmp',
- 'sctp-b-ipv6-egress_action': 'pass',
- 'sctp-a-ipv6-egress_action': 'pass',
- 'Internal1_shared': 'false',
- 'sctp-b-ipv6-ingress_rule_protocol': 'any',
- 'Internal2_net_cidr_len': '17',
- 'sctp-a-name': 'epc-sctp-a-ipv4v6-sec-group',
- 'sctp-a-ingress-src_end_port': '65535.0',
- 'sctp-b-ipv6-ingress_src_subnet_prefix': '0.0.0.0',
- 'sctp-a-egress-dst_end_port': '65535.0',
- 'sctp-a-ingress_action': 'pass',
- 'sctp-b-egress_rule_protocol': 'icmp',
- 'sctp-b-ipv6-ingress_action': 'pass',
- 'vlc_st_service_type': 'firewall',
- 'sctp-b-ipv6-egress_dst_end_port': '65535',
- 'sctp-b-ipv6-ingress-dst_start_port': '0',
- 'vlc2_Internal2_mac': '00:11:22:EF:AC:DF',
- 'vlc_st_availability_zone': 'true',
- 'fsb_volume_image_name_1': 'MME_FSB2_16ACP04_GA.qcow2',
- 'sctp-b-ingress-src_subnet_prefix': '0.0.0.0',
- 'sctp-a-ipv6-ingress_src_subnet_prefix_len': '0',
- 'Internal1_allow_transit': 'true',
- 'gpb_flavor_name': 'nv.c20r64d1',
- 'availability_zone_max_count': '1',
- 'fsb_volume_image_name_0': 'MME_FSB1_16ACP04_GA.qcow2',
- 'sctp-b-ipv6-ingress_dst_addresses': 'local',
- 'sctp-b-ipv6-egress_dst_subnet_prefix': '0.0.0.0',
- 'sctp-b-ipv6-ingress_ethertype': 'IPv4',
- 'vlc1_Internal2_mac': '00:11:22:EF:AC:DF',
- 'sctp-a-ingress-src_subnet_prefix': '0.0.0.0',
- 'sctp-a-ipv6-ingress_action': 'pass',
- 'Internal1_rpf': 'disable',
- 'sctp-b-ingress_ethertype': 'IPv4',
- 'sctp-b-egress_rule_application': 'any',
- 'sctp-b-ingress-src_end_port': '65535.0',
- 'sctp-a-ipv6-ingress_rule_protocol': 'any',
- 'sctp-a-ingress-src_start_port': '0.0',
- 'sctp-b-egress-dst_end_port': '65535.0'
- },
- 'type': 'VF',
- 'modelCustomizationName': 'VF_vGeraldine 0',
- 'vfModules': {
- 'vf_vgeraldine0..VfVgeraldine..vflorence_vlc..module-1': {
- 'uuid': '522159d5-d6e0-4c2a-aa44-5a542a12a830',
- 'invariantUuid': '98a7c88b-b577-476a-90e4-e25a5871e02b',
- 'customizationUuid': '55b1be94-671a-403e-a26c-667e9c47d091',
- 'description': null,
- 'name': 'VfVgeraldine..vflorence_vlc..module-1',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..vflorence_vlc..module-1',
- 'properties': {'minCountInstances': 0, 'maxCountInstances': null, 'initialCount': 0},
- 'commands': {},
- 'volumeGroupAllowed': false
- },
- 'vf_vgeraldine0..VfVgeraldine..vflorence_gpb..module-2': {
- 'uuid': '41708296-e443-4c71-953f-d9a010f059e1',
- 'invariantUuid': '1cca90b8-3490-495e-87da-3f3e4c57d5b9',
- 'customizationUuid': '6add59e0-7fe1-4bc4-af48-f8812422ae7c',
- 'description': null,
- 'name': 'VfVgeraldine..vflorence_gpb..module-2',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..vflorence_gpb..module-2',
- 'properties': {'minCountInstances': 0, 'maxCountInstances': null, 'initialCount': 0},
- 'commands': {},
- 'volumeGroupAllowed': false
- },
- 'vf_vgeraldine0..VfVgeraldine..base_vflorence..module-0': {
- 'uuid': 'a27f5cfc-7f12-4f99-af08-0af9c3885c87',
- 'invariantUuid': 'a6f9e51a-2b35-416a-ae15-15e58d61f36d',
- 'customizationUuid': 'f8c040f1-7e51-4a11-aca8-acf256cfd861',
- 'description': null,
- 'name': 'VfVgeraldine..base_vflorence..module-0',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..base_vflorence..module-0',
- 'properties': {'minCountInstances': 1, 'maxCountInstances': 1, 'initialCount': 1},
- 'commands': {},
- 'volumeGroupAllowed': true
- }
- },
- 'volumeGroups': {
- 'vf_vgeraldine0..VfVgeraldine..base_vflorence..module-0': {
- 'uuid': 'a27f5cfc-7f12-4f99-af08-0af9c3885c87',
- 'invariantUuid': 'a6f9e51a-2b35-416a-ae15-15e58d61f36d',
- 'customizationUuid': 'f8c040f1-7e51-4a11-aca8-acf256cfd861',
- 'description': null,
- 'name': 'VfVgeraldine..base_vflorence..module-0',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..base_vflorence..module-0',
- 'properties': {'minCountInstances': 1, 'maxCountInstances': 1, 'initialCount': 1}
- }
- }
- }
- },
- 'networks': {
- 'ExtVL 0': {
- 'uuid': 'ddc3f20c-08b5-40fd-af72-c6d14636b986',
- 'invariantUuid': '379f816b-a7aa-422f-be30-17114ff50b7c',
- 'description': 'ECOMP generic virtual link (network) base type for all other service-level and global networks',
- 'name': 'ExtVL',
- 'version': '37.0',
- 'customizationUuid': '94fdd893-4a36-4d70-b16a-ec29c54c184f',
- 'inputs': {},
- 'commands': {},
- 'properties': {
- 'network_assignments': '{is_external_network=false, ipv4_subnet_default_assignment={min_subnets_count=1}, ecomp_generated_network_assignment=false, ipv6_subnet_default_assignment={min_subnets_count=1}}',
- 'exVL_naming': '{ecomp_generated_naming=true}',
- 'network_flows': '{is_network_policy=false, is_bound_to_vpn=false}',
- 'network_homing': '{ecomp_selected_instance_node_target=false}'
- },
- 'type': 'VL',
- 'modelCustomizationName': 'ExtVL 0'
- }
- },
- 'configurations': {
- 'Port Mirroring Configuration By Policy 0': {
- 'uuid': 'b4398538-e89d-4f13-b33d-ca323434ba50',
- 'invariantUuid': '6ef0ca40-f366-4897-951f-abd65d25f6f7',
- 'description': 'A port mirroring configuration by policy object',
- 'name': 'Port Mirroring Configuration By Policy',
- 'version': '27.0',
- 'customizationUuid': '3c3b7b8d-8669-4b3b-8664-61970041fad2',
- 'inputs': {},
- 'commands': {},
- 'properties': {},
- 'type': 'Configuration',
- 'modelCustomizationName': 'Port Mirroring Configuration By Policy 0',
- 'sourceNodes': [],
- 'collectorNodes': null,
- 'configurationByPolicy': false
- }
- },
- 'serviceProxies': {},
- 'vfModules': {
- 'vf_vgeraldine0..VfVgeraldine..vflorence_vlc..module-1': {
- 'uuid': '522159d5-d6e0-4c2a-aa44-5a542a12a830',
- 'invariantUuid': '98a7c88b-b577-476a-90e4-e25a5871e02b',
- 'customizationUuid': '55b1be94-671a-403e-a26c-667e9c47d091',
- 'description': null,
- 'name': 'VfVgeraldine..vflorence_vlc..module-1',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..vflorence_vlc..module-1',
- 'properties': {'minCountInstances': 0, 'maxCountInstances': null, 'initialCount': 0},
- 'commands': {},
- 'volumeGroupAllowed': false
- },
- 'vf_vgeraldine0..VfVgeraldine..vflorence_gpb..module-2': {
- 'uuid': '41708296-e443-4c71-953f-d9a010f059e1',
- 'invariantUuid': '1cca90b8-3490-495e-87da-3f3e4c57d5b9',
- 'customizationUuid': '6add59e0-7fe1-4bc4-af48-f8812422ae7c',
- 'description': null,
- 'name': 'VfVgeraldine..vflorence_gpb..module-2',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..vflorence_gpb..module-2',
- 'properties': {'minCountInstances': 0, 'maxCountInstances': null, 'initialCount': 0},
- 'commands': {},
- 'volumeGroupAllowed': false
- },
- 'vf_vgeraldine0..VfVgeraldine..base_vflorence..module-0': {
- 'uuid': 'a27f5cfc-7f12-4f99-af08-0af9c3885c87',
- 'invariantUuid': 'a6f9e51a-2b35-416a-ae15-15e58d61f36d',
- 'customizationUuid': 'f8c040f1-7e51-4a11-aca8-acf256cfd861',
- 'description': null,
- 'name': 'VfVgeraldine..base_vflorence..module-0',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..base_vflorence..module-0',
- 'properties': {'minCountInstances': 1, 'maxCountInstances': 1, 'initialCount': 1},
- 'commands': {},
- 'volumeGroupAllowed': true
- }
- },
- 'volumeGroups': {
- 'vf_vgeraldine0..VfVgeraldine..base_vflorence..module-0': {
- 'uuid': 'a27f5cfc-7f12-4f99-af08-0af9c3885c87',
- 'invariantUuid': 'a6f9e51a-2b35-416a-ae15-15e58d61f36d',
- 'customizationUuid': 'f8c040f1-7e51-4a11-aca8-acf256cfd861',
- 'description': null,
- 'name': 'VfVgeraldine..base_vflorence..module-0',
- 'version': '2',
- 'modelCustomizationName': 'VfVgeraldine..base_vflorence..module-0',
- 'properties': {'minCountInstances': 1, 'maxCountInstances': 1, 'initialCount': 1}
- }
- },
- 'pnfs': {}
- }
- }
- ));
- }
});
shouldOpenVRFModal(nodes, serviceModelId: string , service) {
for(const node of nodes){
if(node.type === 'VRF' && service.serviceInstance[serviceModelId].existingVRFCounterMap && !service.serviceInstance[serviceModelId].existingVRFCounterMap[node.modelUniqueId]){
- const vrfModel : VrfModel = node.getModel(node.name, node, service.serviceInstance[serviceModelId]);
+ const serviceHierarchy = service.serviceHierarchy[serviceModelId];
+
+ const instanceModel = this._sharedTreeService.modelByIdentifiers(
+ serviceHierarchy, node.modelTypeName, node.modelCustomizationId, node.name
+ );
+
+ const vrfModel : VrfModel = node.getModel(instanceModel);
const vrfCounter : number = service.serviceInstance[serviceModelId].existingVRFCounterMap[node.modelUniqueId];
console.log('vrfCounter', vrfCounter);
if(vrfModel.min > 0 && (_.isNil(vrfCounter) || vrfCounter === 0)){
<div class="left-header">
<span class="vid-logo-small"></span>
<span class="icon-back">
- <svg-icon
+ <custom-icon
(click)="closePage()"
[testId]="'backBtn'"
[size]="'large'"
[name]="'navigation-arrow-back'">
- </svg-icon>
+ </custom-icon>
</span>
<div class="header-col middleDetails" style="padding-top: 7px;padding-left: 13px;line-height: 100%;" *ngIf="isServiceFailed">
<ng-template *ngIf="mode !== 'CREATE'" contextMenuItem
(execute)="drawingBoardHeaderService.showAuditInfo(serviceModelId)">
<div [attr.data-tests-id]="'context-menu-header-audit-item'" style="float: left;margin-top: 8px;">
- <svg-icon
+ <custom-icon
[ngClass]="'eye-o'"
class="eye-o"
[size]="'small'"
[name]="'eye-o'">
- </svg-icon></div>
+ </custom-icon></div>
<div style="padding-left: 12px;">Show Audit Info</div>
</ng-template>
<ng-template *ngIf="drawingBoardHeaderService?.showResumeService(serviceModelId)" contextMenuItem
}
- @ViewChild(ContextMenuComponent) public contextMenu: ContextMenuComponent;
+ @ViewChild(ContextMenuComponent, {static: false}) public contextMenu: ContextMenuComponent;
editViewEdit(): void {
window.parent.location.assign(this._drawingBoardHeaderService.generateOldViewEditPath());
}
}
+class MockDragAndDropService<T> {}
describe('Generate path to old View/Edit ', () => {
let injector;
let service: DrawingBoardHeaderService;
import {Injectable} from "@angular/core";
import {NgRedux} from "@angular-redux/store";
import {AppState} from "../../../../shared/store/reducers";
-import {DragAndDropModel} from "./dragAndDrop.model";
import {FeatureFlagsService, Features} from "../../../../shared/services/featureFlag/feature-flags.service";
-import * as _ from 'lodash';
@Injectable()
export class DragAndDropService {
import {NetworkPopupService} from "../../../shared/components/genericFormPopup/genericFormServices/network/network.popup.service";
import {VfModulePopupService} from "../../../shared/components/genericFormPopup/genericFormServices/vfModule/vfModule.popup.service";
import {VnfPopupService} from "../../../shared/components/genericFormPopup/genericFormServices/vnf/vnf.popup.service";
-import {SdcUiServices} from "onap-ui-angular";
import {HighlightPipe} from "../../../shared/pipes/highlight/highlight-filter.pipe";
import {VnfGroupPopupService} from "../../../shared/components/genericFormPopup/genericFormServices/vnfGroup/vnfGroup.popup.service";
import {ObjectToInstanceTreeService} from "../objectsToTree/objectToInstanceTree/objectToInstanceTree.service";
import {ObjectToModelTreeService} from "../objectsToTree/objectToModelTree/objectToModelTree.service";
import {DrawingBoardModes} from "../drawing-board.modes";
import {ServiceInstanceActions} from "../../../shared/models/serviceInstanceActions";
+import {ModalService} from "../../../shared/components/customModal/services/modal.service";
@Component({
selector: 'drawing-board-tree',
static triggerDeleteActionService: Subject<string> = new Subject<string>();
static triggerUndoDeleteActionService: Subject<string> = new Subject<string>();
static triggerreCalculateIsDirty: Subject<string> = new Subject<string>();
- @ViewChild(ContextMenuComponent) public contextMenu: ContextMenuComponent;
+ @ViewChild(ContextMenuComponent, {static: false}) public contextMenu: ContextMenuComponent;
constructor(private _contextMenuService: ContextMenuService,
private _iframeService: IframeService,
private store: NgRedux<AppState>,
private route: ActivatedRoute,
private _duplicateService: DuplicateService,
- private modalService: SdcUiServices.ModalService,
+ private modalService: ModalService,
private _drawingBoardTreeService: DrawingBoardTreeService,
private _networkPopupService: NetworkPopupService,
private _vfModulePopuopService: VfModulePopupService,
@Output()
highlightNode: EventEmitter<number> = new EventEmitter<number>();
- @ViewChild('tree') tree: TreeComponent;
+ @ViewChild('tree', {static: false}) tree: TreeComponent;
missingDataTooltip: string = Constants.Error.MISSING_VNF_DETAILS;
currentNode: ITreeNode = null;
flags: any;
this.highlightNode.emit(node.data.modelUniqueId);
if (FeatureFlagsService.getFlagState(Features.FLAG_1906_COMPONENT_INFO, this.store)) {
const serviceHierarchy = this._store.getState().service.serviceHierarchy[this.serviceModelId];
- const model = node.data.getModel(node.data.modelName, node.data, serviceHierarchy);
+
+ const instanceModel = this._sharedTreeService.modelByIdentifiers(
+ serviceHierarchy, node.data.modelTypeName,
+ this._sharedTreeService.modelUniqueNameOrId(node.data), node.data.modelName
+ );
+
+ const model = node.data.getModel(instanceModel);
const modelInfoItems = node.data.getInfo(model, node.data);
const componentInfoModel: ComponentInfoModel = this._sharedTreeService.addGeneralInfoItems(modelInfoItems, node.data.componentInfoType, model, node.data);
ComponentInfoService.triggerComponentInfoChange.next(componentInfoModel);
<div><span title="{{node.data.type}}"
[attr.data-tests-id]="'node-type-indicator'">{{node?.data?.typeName}}</span></div>
<div *ngIf="isLinkedInstance(node?.data)">
- <svg-icon
+ <custom-icon
[ngClass]="'link'"
class="icon-link"
[size]="'small'"
[name]="'link'">
- </svg-icon>
+ </custom-icon>
</div>
</div>
<div class="model-info" [ngClass]="{'rightBorder' : pageMode === 'VIEW'}">
[enabled]="isEnabled(currentNode, serviceModelId, contextMenuOption.methodName)">
<div [attr.data-tests-id]="contextMenuOption.dataTestId">
<div style="float: left;margin-top: 3px;">
- <svg-icon
+ <custom-icon
class="icon-edit"
[ngClass]="contextMenuOption.iconClass"
[size]="'small'"
[name]="contextMenuOption.iconClass">
- </svg-icon></div>
+ </custom-icon></div>
<div style="padding-left: 25px;">{{getcontextMenuOptionLabel(contextMenuOption)}}</div>
</div>
</ng-template>
tooltipPlacement="left"
[attr.data-tests-id]="'node-'+ node.data.modelId + '-' + node.data.modelName +'-alert-icon'"
class="icon-alert">
- <svg-icon
+ <custom-icon
[mode]="'warning'"
[testId]="'icon-alert'"
[size]="'medium'"
[name]="'alert-triangle-o'">
- </svg-icon>
+ </custom-icon>
</span>
</div>
import {LogService} from '../../../shared/utils/log/log.service';
import {NgRedux} from '@angular-redux/store';
import {ITreeNode} from "angular-tree-component/dist/defs/api";
-import {SdcUiServices} from "onap-ui-angular";
-import {IModalConfig} from 'onap-ui-angular/dist/components/common';
import {AppState} from "../../../shared/store/reducers";
import {getTestBed, TestBed} from "@angular/core/testing";
import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service";
import {SharedTreeService} from "../objectsToTree/shared.tree.service";
+import {IModalConfig} from "../../../shared/components/customModal/models/modal.model";
+import {ModalService} from "../../../shared/components/customModal/services/modal.service";
class MockAppStore<T> {
getState(){
LogService,
{provide: FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockAppStore},
- {provide: SdcUiServices.ModalService, useClass: MockModalService}
+ {provide: ModalService, useClass: MockModalService}
]
});
await TestBed.compileComponents();
import * as _ from "lodash";
import {DefaultDataGeneratorService} from "../../../shared/services/defaultDataServiceGenerator/default.data.generator.service";
import {TypeNodeInformation} from "../typeNodeInformation.model";
-import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
+import {SdcUiCommon} from "onap-ui-angular";
import {changeInstanceCounter, duplicateBulkInstances} from "../../../shared/storeUtil/utils/general/general.actions";
import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config";
import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service";
import {Utils} from "../../../shared/utils/utils";
import {SharedTreeService} from "../objectsToTree/shared.tree.service";
+import {ModalService} from "../../../shared/components/customModal/services/modal.service";
@Injectable()
export class DuplicateService {
constructor(private _logService: LogService,
private sharedTreeService : SharedTreeService,
- private _store: NgRedux<AppState>, modalService: SdcUiServices.ModalService) {
+ private _store: NgRedux<AppState>, modalService: ModalService) {
this.modalService = modalService;
}
maxNumberOfDuplicate: number = 0;
storeKey: string = null;
padding = '0000';
- modalService: SdcUiServices.ModalService;
+ modalService: ModalService;
store: NgRedux<AppState>;
existingNames: { [key: string]: any };
currentNode: ITreeNode = null;
import {ITreeNode} from "angular-tree-component/dist/defs/api";
import {AvailableNodeIcons} from "../../available-models-tree/available-models-tree.service";
-import {ComponentInfoModel, ComponentInfoType} from "../../component-info/component-info-model";
+import {ComponentInfoType} from "../../component-info/component-info-model";
import {ModelInformationItem} from "../../../../shared/components/model-information/model-information.component";
export interface ILevelNodeInfo {
updatePosition(node, that, instanceId, parentStoreKey?) : void;
/***********************************************************
- * return object instance
- * @param modelId - The model id
- * @param serviceHierarchy - The serviceHierarchy store
- * @param instance - existing instance details
+ * return a NodeModel object instance
+ * @param instanceModel - The model of the instance (usually extracted from
+ * serviceHierarchy store)
************************************************************/
- getModel(modelId: string, instance: any, serviceHierarchy): any;
+ getModel(instanceModel: any): any;
/***********************************************************
* return dynamic inputs of current model
* @param model - The model of current object
* @param parentModel
* @param storeKey - instance storeKey if exist (for duplicate)
+ * @param serviceModelId
************************************************************/
- createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string): any
+ createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any
/***********************************************************
* return if instance has some missing data
let collectionResourceModel: CollectionResourceModelInfo;
let _sharedTreeService : SharedTreeService;
- beforeEach(() => {
+ beforeEach(done => (async () => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, NgReduxTestingModule],
providers: [
FeatureFlagsService,
ComponentInfoService,
IframeService]
- }).compileComponents();
-
+ });
+ await TestBed.compileComponents();
injector = getTestBed();
_store = injector.get(NgRedux);
_componentInfoService = injector.get(ComponentInfoService);
+ _sharedTreeService = injector.get(SharedTreeService);
collectionResourceModel = new CollectionResourceModelInfo(_store, _sharedTreeService);
- });
+ })().then(done).catch(done.fail));
test('collection resource should be defined', () => {
expect(collectionResourceModel).toBeDefined();
});
test('getModel should return collectionResource model', () => {
- let model: CollectionResourceModel = collectionResourceModel.getModel('CR_sanity 0', <any>{
- originalName : 'CR_sanity 0'
- }, getServiceHierarchy());
- expect(model.type).toEqual('CR');
+ expect(collectionResourceModel.getModel({})).toBeInstanceOf(CollectionResourceModel);
});
test('cr getMenuAction: delete', ()=>{
expect(result['delete']['method']).toHaveBeenCalledWith(node, serviceModelId);
});
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "collectionResources": {
- "CR_sanity 0": {
- "uuid": "3467f91f-1a2a-4013-a5ed-8ad99d4e06ad",
- "invariantUuid": "d0060da6-82b8-4ca0-9758-5eb2b111b926",
- "description": "CR_sanity",
- "name": "CR_sanity",
- "version": "1.0",
- "customizationUuid": "7160c618-9314-4c09-8717-b77f3d29d946",
- "inputs": {},
- "commands": {},
- "properties": {
- "cr_sanity..Fixed..0_quantity": "10",
- "cr_sanity..NetworkCollection..0_network_collection_function": "ABCD",
- "ecomp_generated_naming": "false",
- "cr_sanity..NetworkCollection..0_network_collection_description": "ABCD"
- },
- "type": "CR",
- "category": "Network L2-3",
- "subcategory": "Infrastructure",
- "resourceVendor": "ATT",
- "resourceVendorRelease": "2018.06",
- "resourceVendorModelNumber": "",
- "customizationUUID": "7160c618-9314-4c09-8717-b77f3d29d946",
- "networksCollection": {
- "cr_sanity..NetworkCollection..0": {
- "uuid": "445d7fa8-3e59-4606-bd76-30ba5fc677d3",
- "invariantUuid": "9dc623b8-0ae8-47ad-a791-a21b8d8e94a8",
- "name": "cr_sanity..NetworkCollection..0",
- "version": "1",
- "networkCollectionProperties": {
- "networkCollectionFunction": "ABCD",
- "networkCollectionDescription": "ABCD"
- }
- }
- }
- }
- },
- "vnfs": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-388_PASQUALE-vPE 0": {
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "4.0",
- "customizationUuid": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-488_PASQUALE-vPE 0": {
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-488_PASQUALE-vPE",
- "version": "5.0",
- "customizationUuid": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "max_instances": "3",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "vfcInstanceGroups": {}
- }
- },
- "networks": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "pnfs": {}
- }
- }
-
});
updateDynamicInputsDataFromModel = (currentModel): any => [];
- getModel = (collectionResourceModelId: string, instance: CollectionResourceInstance, serviceHierarchy): CollectionResourceModel => {
- const originalModelName = instance.originalName ? instance.originalName : collectionResourceModelId;
- return new CollectionResourceModel(serviceHierarchy[this.name][originalModelName]);
+ getModel = (instanceModel): CollectionResourceModel => {
+ return new CollectionResourceModel(instanceModel);
};
-
- createInstanceTreeNode = (instance: CollectionResourceInstance, model: CollectionResourceModel, parentModel, storeKey: string): CollectionResourceTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let node = new CollectionResourceTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
return node;
import {HttpClientTestingModule} from "@angular/common/http/testing";
-import {TestBed} from "@angular/core/testing";
+import {getTestBed, TestBed} from "@angular/core/testing";
import {MockNgRedux, NgReduxTestingModule} from "@angular-redux/store/testing";
import {DynamicInputsService} from "../../dynamicInputs.service";
import {ConfigurationModelInfo} from "./configuration.model.info";
import {SharedTreeService} from "../../shared.tree.service";
describe('Vnf Model Info', () => {
+ let injector;
let _dynamicInputsService : DynamicInputsService;
let _sharedTreeService : SharedTreeService;
DynamicInputsService]
});
await TestBed.compileComponents();
+
+ injector = getTestBed();
+ _sharedTreeService = injector.get(SharedTreeService);
})().then(done).catch(done.fail));
test('ConfigurationModelInfo should be defined', () => {
test('getModel should return Configuration model', () => {
let configurationModelInfo: ConfigurationModelInfo = new ConfigurationModelInfo(_dynamicInputsService, _sharedTreeService);
- let model = configurationModelInfo.getModel('2017-388_PASQUALE-vPE 1__configuration', getServiceHierarchy());
- expect(model.uuid).toEqual('0903e1c0-8e03-4936-b5c2-260653b96413');
+ let model = configurationModelInfo.getModel({ uuid: 'foo' });
+ expect(model.uuid).toEqual('foo');
});
-
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "vnfs": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-388_PASQUALE-vPE 0": {
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "4.0",
- "customizationUuid": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-488_PASQUALE-vPE 0": {
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-488_PASQUALE-vPE",
- "version": "5.0",
- "customizationUuid": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "max_instances": "3",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "vfcInstanceGroups": {}
- }
- },
- "networks": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- }
- },
- "collectionResources": {},
- "configurations": {
- "2017-388_PASQUALE-vPE 1__configuration": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- }
-
- },
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "pnfs": {}
- }
- }
});
getType = () : string => "Configuration";
/***********************************************************
- * return configuration model
- * @param configurationModelId - current Model id
- * @param serviceHierarchy - serviceHierarchy
+ * @param instanceModel - The model of the instance (usually extracted from serviceHierarchy store)
************************************************************/
- getModel = (configurationModelId : string, serviceHierarchy) : any =>{
- if(!_.isNil(serviceHierarchy)){
- if(!_.isNil(serviceHierarchy[this.name]) && !_.isNil(serviceHierarchy[this.name][configurationModelId])){
- return serviceHierarchy[this.name][configurationModelId];
- }
+ getModel = (instanceModel: any) : any =>{
+ if (!_.isNil(instanceModel)) {
+ return instanceModel;
}
return {};
};
- createInstanceTreeNode(instance: any, model: any, storeKey: string): any {return null;}
+ createInstanceTreeNode(instance: any, model: any, storeKey: string, serviceModelId: string): any {return null;}
childNames: string[];
typeName: "NCF"
};
- const ncfTreeNode: NcfTreeNode = ncfModel.createInstanceTreeNode(instance, {}, parentModel, "6b3536cf-3a12-457f-abb5-fa2203e0d923");
+ const ncfTreeNode: NcfTreeNode = ncfModel.createInstanceTreeNode(instance, {}, parentModel, "6b3536cf-3a12-457f-abb5-fa2203e0d923", "dd182d7d-6949-4b90-b3cc-5befe400742e");
expect(ncfTreeNode).toMatchObject(expected);
});
updateDynamicInputsDataFromModel = (currentModel): any => [];
- getModel = (modelId: string, instance: any, serviceHierarchy): any => {
+ getModel = (instanceModel: any): any => {
return new Level1Model();
};
- createInstanceTreeNode = (instance: Level1Instance, model: Level1Model, parentModel, storeKey: string): NcfTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let modelVersion: string = null;
if (parentModel.networksCollection && instance.originalName) {
const ncfRealModel: NcfModelInterface = parentModel.networksCollection[instance.originalName];
}
let node = new NcfTreeNode(instance, model, storeKey, modelVersion);
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.typeName = this.typeName;
return node;
};
import {DuplicateService} from "../../../duplicate/duplicate.service";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
+import {NetworkModel} from "../../../../../shared/models/networkModel";
class MockAppStore<T> {
getState() {
});
test('getModel should return Network model', () => {
- let model = networkModel.getModel('2017-388_PASQUALE-vPE 1_1', <any>{}, getServiceHierarchy());
- expect(model.type).toEqual('VL');
+ expect(networkModel.getModel({})).toBeInstanceOf(NetworkModel);
});
test('showNodeIcons should return false if reachLimit of max', () => {
};
}
-
- function getServiceHierarchy() {
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "vnfs": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-388_PASQUALE-vPE 0": {
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "4.0",
- "customizationUuid": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-488_PASQUALE-vPE 0": {
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-488_PASQUALE-vPE",
- "version": "5.0",
- "customizationUuid": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "max_instances": "3",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "vfcInstanceGroups": {}
- }
- },
- "networks": {
- "2017-388_PASQUALE-vPE 1_1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VL",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- }
- },
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "pnfs": {}
- }
- }
});
import {DynamicInputsService} from "../../dynamicInputs.service";
import {ILevelNodeInfo} from "../basic.model.info";
-import {NetworkInstance} from "../../../../../shared/models/networkInstance";
import {NetworkModel} from "../../../../../shared/models/networkModel";
import {NetworkTreeNode} from "../../../../../shared/models/networkTreeNode";
import {SharedTreeService} from "../../shared.tree.service";
import {InputType} from "../../../../../shared/models/inputTypes";
import {NgRedux} from "@angular-redux/store";
import {AppState} from "../../../../../shared/store/reducers";
-import {GenericFormPopupComponent, PopupType} from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
+import {
+ GenericFormPopupComponent,
+ PopupType
+} from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
import {DialogService} from "ng2-bootstrap-modal";
import {NetworkPopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/network/network.popup.service";
import * as _ from "lodash";
import {DuplicateVnfComponent} from "../../../duplicate/duplicate-vnf.component";
import {changeInstanceCounter, removeInstance} from "../../../../../shared/storeUtil/utils/general/general.actions";
import {IframeService} from "../../../../../shared/utils/iframe.service";
-import {SdcUiServices} from "onap-ui-angular";
import {DuplicateService} from "../../../duplicate/duplicate.service";
import {ServiceInstanceActions} from "../../../../../shared/models/serviceInstanceActions";
-import {deleteActionNetworkInstance, undoDeleteActionNetworkInstance, updateNetworkPosition} from "../../../../../shared/storeUtil/utils/network/network.actions";
+import {
+ deleteActionNetworkInstance,
+ undoDeleteActionNetworkInstance,
+ updateNetworkPosition
+} from "../../../../../shared/storeUtil/utils/network/network.actions";
import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config";
import {ComponentInfoType} from "../../../component-info/component-info-model";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
+import {ModalService} from "../../../../../shared/components/customModal/services/modal.service";
export class NetworkModelInfo implements ILevelNodeInfo {
constructor(private _dynamicInputsService: DynamicInputsService,
private _dialogService: DialogService,
private _networkPopupService: NetworkPopupService,
private _duplicateService: DuplicateService,
- private modalService: SdcUiServices.ModalService,
+ private modalService: ModalService,
private _iframeService: IframeService,
private _featureFlagsService: FeatureFlagsService,
private _store: NgRedux<AppState>) {
};
/***********************************************************
- * return network model
- * @param networkModelId - current Model id
- * @param instance
- * @param serviceHierarchy - serviceHierarchy
+ * return a NodeModel object instance
+ * @param instanceModel - The model of the instance (usually extracted from serviceHierarchy store)
************************************************************/
- getModel = (networkModelId: string, instance: NetworkInstance, serviceHierarchy): NetworkModel => {
- const originalModelName = instance.originalName ? instance.originalName : networkModelId;
- return new NetworkModel(serviceHierarchy[this.name][originalModelName], this._featureFlagsService.getAllFlags());
+ getModel = (instanceModel: any): NetworkModel => {
+ return new NetworkModel(
+ instanceModel,
+ this._featureFlagsService.getAllFlags());
};
* @param parentModel
* @param storeKey - store key if exist
************************************************************/
- createInstanceTreeNode = (instance: NetworkInstance, model: NetworkModel, parentModel, storeKey: string): NetworkTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let node = new NetworkTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
node = this._sharedTreeService.addingStatusProperty(node);
});
}
},
- visible: (node) => node.data.parentType !== 'VRF' && this._sharedTreeService.shouldShowDelete(node),
- enable: (node) => node.data.parentType !== 'VRF' && this._sharedTreeService.shouldShowDelete(node)
+ visible: (node) => node.data.parentType !== 'VRF' && this._sharedTreeService.shouldShowDelete(node, serviceModelId),
+ enable: (node) => node.data.parentType !== 'VRF' && this._sharedTreeService.shouldShowDelete(node, serviceModelId)
},
undoDelete: {
method: (node, serviceModelId) => {
import {HttpClient, HttpHandler} from "@angular/common/http";
import {CollectionResourceModel} from "../../../../../shared/models/collectionResourceModel";
import {ComponentInfoType} from "../../../component-info/component-info-model";
+import {VNFModel} from "../../../../../shared/models/vnfModel";
+import {PNFModel} from "../../../../../shared/models/pnfModel";
describe('PNF model info', () => {
let injector;
let _componentInfoService: ComponentInfoService;
let _store: NgRedux<AppState>;
- let pnfModel: PnfModelInfo = new PnfModelInfo();
- beforeEach(() => {
+ let _sharedTreeService;
+ let pnfModel: PnfModelInfo;
+ beforeEach(done => (async () => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, NgReduxTestingModule],
providers: [
FeatureFlagsService,
ComponentInfoService,
IframeService]
- }).compileComponents();
-
+ });
+ await TestBed.compileComponents();
injector = getTestBed();
_store = injector.get(NgRedux);
+ _sharedTreeService = injector.get(SharedTreeService);
+ pnfModel = new PnfModelInfo(_sharedTreeService);
_componentInfoService = injector.get(ComponentInfoService);
- });
+ })().then(done).catch(done.fail));
test('pnf model should be defined', () => {
expect(pnfModel).toBeDefined();
});
test('getModel should return pnf model', () => {
- let model: CollectionResourceModel = pnfModel.getModel('PNF1', <any>{
- originalName : 'PNF1'
- }, getServiceHierarchy());
- expect(model.type).toEqual('PNF');
+ expect(pnfModel.getModel({})).toBeInstanceOf(PNFModel);
});
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "12550cd7-7708-4f53-a09e-41d3d6327ebc",
- "invariantUuid": "561faa57-7bbb-40ec-a81c-c0d4133e98d4",
- "name": "AIM Transport SVC_ym161f",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "Network L1-3",
- "serviceType": "TRANSPORT",
- "serviceRole": "AIM",
- "description": "AIM Transport service",
- "serviceEcompNaming": "true",
- "instantiationType": "Macro",
- "inputs": {},
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other",
- "viewEditUI": "legacy"
- }
- },
- "vnfs": {},
- "networks": {},
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {},
- "volumeGroups": {},
- "pnfs": {
- "PNF1": {
- "uuid": "1c831fa9-28a6-4778-8c1d-80b9e769f2ed",
- "invariantUuid": "74e13a12-dac9-4fba-b102-cd242d9e7f02",
- "description": "AIM Transport service",
- "name": "AIM PNF Model",
- "version": "1.0",
- "customizationUuid": "dce78da7-c842-47a1-aba2-2de1cd03ab7a",
- "inputs": {},
- "commands": {},
- "properties": {
- "nf_function": "SDNGW",
- "nf_role": "pD2IPE",
- "ecomp_generated_naming": "false",
- "nf_type": "ROUTER"
- },
- "type": "PNF"
- }
- },
- "vnfGroups": {}
- }
- }
})
import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
import {PnfInstance} from "app/shared/models/pnfInstance";
import {PNFModel} from "../../../../../shared/models/pnfModel";
-import {PnfTreeNode} from "../../../../../shared/models/pnfTreeNode";
+import {SharedTreeService} from "../../shared.tree.service";
+import {NodeModelResponseInterface} from "../../../../../shared/models/nodeModel";
export class PnfModelInfo implements ILevelNodeInfo{
- constructor(){}
+ constructor(
+ private _sharedTreeService: SharedTreeService,
+ ){}
name: string = 'pnfs';
type: string ='PNF';
childNames: string[];
componentInfoType = ComponentInfoType.PNF;
- createInstanceTreeNode = (instance: PnfInstance, model: PNFModel, parentModel: any, storeKey: string): PnfTreeNode => null;
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => null;
getInfo(model, instance): ModelInformationItem[] {
return [];
return {};
}
- getModel = (pnfModelId: string, instance: PnfInstance, serviceHierarchy): PNFModel => {
- const originalModelName = instance.originalName ? instance.originalName : pnfModelId;
- return new PNFModel(serviceHierarchy[this.name][originalModelName]);
+ getModel = (instanceModel: any): PNFModel => {
+ return new PNFModel(instanceModel);
};
getNextLevelObject(): any { return null; }
});
test('getModel should return VNF model', () => {
- let model: VNFModel = relatedVnfMemeber.getModel('2017-388_PASQUALE-vPE 1', <any>{
- originalName : '2017-388_PASQUALE-vPE 1'
- }, getServiceHierarchy());
- expect(model.type).toEqual('VF');
+ expect(relatedVnfMemeber.getModel({})).toBeInstanceOf(VNFModel);
});
expect(result['undoDelete']['method']).toHaveBeenCalledWith(node, serviceModelId);
});
-
-
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "vnfs": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-388_PASQUALE-vPE 0": {
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "4.0",
- "customizationUuid": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-488_PASQUALE-vPE 0": {
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-488_PASQUALE-vPE",
- "version": "5.0",
- "customizationUuid": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "max_instances": "3",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "vfcInstanceGroups": {}
- }
- },
- "networks": {},
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "pnfs": {}
- }
- }
});
removeRelatedVnfMemberInstance,
undoDeleteActionRelatedVnfMemberInstance
} from "../../../../../shared/storeUtil/utils/relatedVnfMember/relatedVnfMember.actions";
-import {VnfInstance} from "../../../../../shared/models/vnfInstance";
import {VNFModel} from "../../../../../shared/models/vnfModel";
import {VnfTreeNode} from "../../../../../shared/models/vnfTreeNode";
import {InputType} from "../../../../../shared/models/inputTypes";
};
/***********************************************************
- * return vnf model
- * @param vnfModelId - current Model id
- * @param instance - vnf instance
- * @param serviceHierarchy - serviceHierarchy
+ * return a NodeModel object instance
+ * @param instanceModel - The model of the instance (usually extracted from
+ * serviceHierarchy store)
************************************************************/
- getModel = (vnfModelId: string, instance: VnfInstance, serviceHierarchy): VNFModel => {
- const originalModelName = instance.originalName ? instance.originalName : vnfModelId;
- return new VNFModel(serviceHierarchy[this.name][originalModelName]);
+ getModel = (instanceModel: any): VNFModel => {
+ return new VNFModel(instanceModel);
};
* @param model - vnf model
* @param parentModel
* @param storeKey - store key if exist
+ * @param serviceModelId
************************************************************/
- createInstanceTreeNode = (instance: VnfInstance, model: VNFModel, parentModel, storeKey: string): VnfTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let node = new VnfTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage: "";
node = this._sharedTreeService.addingStatusProperty(node);
method : (node, serviceModelId) => {
this._store.dispatch(deleteActionRelatedVnfMemberInstance(node.parent.data.vnfGroupStoreKey, node.data.vnfStoreKey, serviceModelId));
},
- visible: (node) => this._sharedTreeService.shouldShowDelete(node),
- enable: (node) => this._sharedTreeService.shouldShowDelete(node)
+ visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
+ enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
},
undoDelete : {
method : (node, serviceModelId) => {
},
visible: (node) => this._sharedTreeService.shouldShowUndoDelete(node),
- enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && this._sharedTreeService.shouldShowDelete(node.parent) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
+ enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && this._sharedTreeService.shouldShowDelete(node.parent, serviceModelId) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
}
}
}
});
test('getModel should return Module model', () => {
- let model = vfModuleModel.getModel('2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1',null, getServiceHierarchy());
+ let model = vfModuleModel.getModel({
+ "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
+ "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
+ "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
+ "description": null,
+ "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+ "version": "6",
+ "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+ "properties": {
+ "minCountInstances": 2,
+ "maxCountInstances": 3,
+ "initialCount": 0,
+ "vfModuleLabel": "PASQUALE_vRE_BV",
+ "baseModule": false
+ },
+ "inputs": {
+ "vnf_config_template_version": {
+ "type": "string"
+ }
+ },
+ "volumeGroupAllowed": true
+ });
+ expect(model).toBeInstanceOf(VfModule);
expect(model.uuid).toEqual('25284168-24bb-4698-8cb4-3f509146eca5');
expect(model.min).toBe(2);
expect(model.max).toBe(3);
};
}
-
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "vnfs": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-388_PASQUALE-vPE 0": {
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "4.0",
- "customizationUuid": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-488_PASQUALE-vPE 0": {
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-488_PASQUALE-vPE",
- "version": "5.0",
- "customizationUuid": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "max_instances": "3",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1":{
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 2,
- "maxCountInstances": 3,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "vfcInstanceGroups": {}
- }
- },
- "networks": {},
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 2,
- "maxCountInstances": 3,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "pnfs": {}
- }
- }
});
/***********************************************************
* return vfModule model
- * @param vfModuleModelId - current Model id
- * @param instance
- * @param serviceHierarchy - serviceHierarchy
+ * @param instanceModel - The model of the instance (usually extracted from
+ * serviceHierarchy store)
************************************************************/
- getModel = (vfModuleModelId: string, instance, serviceHierarchy): Partial<VfModule> => {
- if (!_.isNil(serviceHierarchy)) {
- if (!_.isNil(serviceHierarchy[this.name]) && !_.isNil(serviceHierarchy[this.name][vfModuleModelId])) {
- return new VfModule(serviceHierarchy[this.name][vfModuleModelId], this._featureFlagsService.getAllFlags());
- }
+ getModel = (instanceModel: any): Partial<VfModule> => {
+ if (!_.isNil(instanceModel)) {
+ return new VfModule(instanceModel, this._featureFlagsService.getAllFlags());
}
return {};
};
- createNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string, index: number): VfModuleTreeNode {
+ createNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string, index: number, serviceModelId: string): VfModuleTreeNode {
let dynamicModelName = Object.keys(instance)[index];
instance = instance[Object.keys(instance)[index]];
const isEcompGeneratedNaming: boolean = this.isEcompGeneratedNaming(currentModel, parentModel);
newVfModule.missingData = this._sharedTreeService.hasMissingData(instance, newVfModule.dynamicInputs, isEcompGeneratedNaming, []);
newVfModule.typeName = this.typeName;
- newVfModule.menuActions = this.getMenuAction(<any>newVfModule, currentModel.uuid);
+ newVfModule.menuActions = this.getMenuAction(<any>newVfModule, serviceModelId);
newVfModule.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
newVfModule.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
return newVfModule;
}
- createInstanceTreeNode(instance: VfModuleInstance, currentModel: VfModule, parentModel: VNFModel, modelName: string): VfModuleTreeNode | VfModuleTreeNode[] {
+ createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any {
let numberOfChilds = Object.keys(instance).length;
if (numberOfChilds > 1) {
let result: VfModuleTreeNode[] = [];
for (let i = 0; i < numberOfChilds; i++) {
- result.push(this.createNode(instance, currentModel, parentModel, modelName, i));
+ result.push(this.createNode(instance, model, parentModel, storeKey, i, serviceModelId));
}
return result;
} else {
- return this.createNode(instance, currentModel, parentModel, modelName, 0);
+ return this.createNode(instance, model, parentModel, storeKey, 0, serviceModelId);
}
}
method: (node, serviceModelId) => {
this._store.dispatch(deleteActionVfModuleInstance(node.data.dynamicModelName, node.parent.data.vnfStoreKey, serviceModelId))
},
- visible: (node) => this._sharedTreeService.shouldShowDelete(node),
- enable: (node) => this._sharedTreeService.shouldShowDelete(node)
+ visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
+ enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
},
undoDelete: {
method: (node, serviceModelId) => {
this._store.dispatch(deleteVFModuleField(node.data.modelName, node.parent.data.vnfStoreKey, node.data.servicedId ,node.data.dynamicModelName, 'retainAssignments'));
},
visible: (node) => this._sharedTreeService.shouldShowUndoDelete(node),
- enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && this._sharedTreeService.shouldShowDelete(node.parent) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
+ enable: (node, serviceModelId) => this._sharedTreeService.shouldShowUndoDelete(node) && this._sharedTreeService.shouldShowDelete(node.parent, serviceModelId) && !this._sharedTreeService.isServiceOnDeleteMode(serviceModelId)
},
upgrade: {
method: (node, serviceModelId) => {
});
test('getModel should return VNF model', () => {
- let model: VNFModel = vnfModel.getModel('2017-388_PASQUALE-vPE 1', <any>{
- originalName : '2017-388_PASQUALE-vPE 1'
- }, getServiceHierarchy());
- expect(model.type).toEqual('VF');
+ expect(vnfModel.getModel({})).toBeInstanceOf(VNFModel);
});
test('showNodeIcons should return false if reachLimit of max', ()=>{
};
}
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "vnfs": {
- "2017-388_PASQUALE-vPE 1": {
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "1.0",
- "customizationUuid": "280dec31-f16d-488b-9668-4aae55d6648a",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-388_PASQUALE-vPE 0": {
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-388_PASQUALE-vPE",
- "version": "4.0",
- "customizationUuid": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "vfModules": {},
- "volumeGroups": {},
- "vfcInstanceGroups": {}
- },
- "2017-488_PASQUALE-vPE 0": {
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "invariantUuid": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "description": "Name PASQUALE vPE Description The provider edge function for the PASQUALE service supported by the Junipers VMX product Category Router Vendor Juniper Vendor Release Code 17.2 Owners Mary Fragale. Updated 9-25 to use v8.0 of the Juniper Valid 2 VLM",
- "name": "2017-488_PASQUALE-vPE",
- "version": "5.0",
- "customizationUuid": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "ATLMY8GA"
- },
- "ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "commands": {
- "vnf_config_template_version": {
- "displayName": "vnf_config_template_version",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_config_template_version"
- },
- "bandwidth_units": {
- "displayName": "bandwidth_units",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth_units"
- },
- "bandwidth": {
- "displayName": "bandwidth",
- "command": "get_input",
- "inputName": "pasqualevpe0_bandwidth"
- },
- "AIC_CLLI": {
- "displayName": "AIC_CLLI",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_AIC_CLLI"
- },
- "ASN": {
- "displayName": "ASN",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_ASN"
- },
- "vnf_instance_name": {
- "displayName": "vnf_instance_name",
- "command": "get_input",
- "inputName": "2017488_pasqualevpe0_vnf_instance_name"
- }
- },
- "properties": {
- "vmxvre_retype": "RE-VMX",
- "vnf_config_template_version": "get_input:2017488_pasqualevpe0_vnf_config_template_version",
- "sriov44_net_id": "48d399b3-11ee-48a8-94d2-f0ea94d6be8d",
- "int_ctl_net_id": "2f323477-6936-4d01-ac53-d849430281d9",
- "vmxvpfe_sriov41_0_port_mac": "00:11:22:EF:AC:DF",
- "int_ctl_net_name": "VMX-INTXI",
- "vmx_int_ctl_prefix": "10.0.0.10",
- "sriov43_net_id": "da349ca1-6de9-4548-be88-2d88e99bfef5",
- "sriov42_net_id": "760669ba-013d-4d9b-b0e7-4151fe2e6279",
- "sriov41_net_id": "25ad52d5-c165-40f8-b3b0-ddfc2373280a",
- "nf_type": "vPE",
- "vmxvpfe_int_ctl_ip_1": "10.0.0.10",
- "is_AVPN_service": "false",
- "vmx_RSG_name": "vREXI-affinity",
- "vmx_int_ctl_forwarding": "l2",
- "vmxvre_oam_ip_0": "10.0.0.10",
- "vmxvpfe_sriov44_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_sriov41_0_port_vlanstrip": "false",
- "vmxvpfe_sriov42_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov44_0_port_unknownunicastallow": "true",
- "vmxvre_image_name_0": "VRE-ENGINE_17.2-S2.1.qcow2",
- "vmxvre_instance": "0",
- "vmxvpfe_sriov43_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvre_flavor_name": "ns.c1r16d32.v5",
- "vmxvpfe_volume_size_0": "40.0",
- "vmxvpfe_sriov43_0_port_vlanfilter": "4001",
- "nf_naming": "{ecomp_generated_naming=false}",
- "nf_naming_code": "Navneet",
- "vmxvre_name_0": "vREXI",
- "vmxvpfe_sriov42_0_port_vlanstrip": "false",
- "vmxvpfe_volume_name_0": "vPFEXI_FBVolume",
- "max_instances": "3",
- "vmx_RSG_id": "bd89a33c-13c3-4a04-8fde-1a57eb123141",
- "vmxvpfe_image_name_0": "VPE_ROUTING-ENGINE_17.2R1-S2.1.qcow2",
- "vmxvpfe_sriov43_0_port_unknownunicastallow": "true",
- "vmxvpfe_sriov44_0_port_unknownmulticastallow": "true",
- "vmxvre_console": "vidconsole",
- "vmxvpfe_sriov44_0_port_vlanfilter": "4001",
- "vmxvpfe_sriov42_0_port_mac": "00:11:22:EF:AC:DF",
- "vmxvpfe_volume_id_0": "47cede15-da2f-4397-a101-aa683220aff3",
- "vmxvpfe_sriov42_0_port_unknownmulticastallow": "true",
- "min_instances": "1",
- "vmxvpfe_sriov44_0_port_vlanstrip": "false",
- "vf_module_id": "123",
- "nf_function": "JAI",
- "vmxvpfe_sriov43_0_port_unknownmulticastallow": "true",
- "vmxvre_int_ctl_ip_0": "10.0.0.10",
- "ecomp_generated_naming": "false",
- "AIC_CLLI": "get_input:2017488_pasqualevpe0_AIC_CLLI",
- "vnf_name": "mtnj309me6vre",
- "vmxvpfe_sriov41_0_port_unknownunicastallow": "true",
- "vmxvre_volume_type_1": "HITACHI",
- "vmxvpfe_sriov44_0_port_broadcastallow": "true",
- "vmxvre_volume_type_0": "HITACHI",
- "vmxvpfe_volume_type_0": "HITACHI",
- "vmxvpfe_sriov43_0_port_broadcastallow": "true",
- "bandwidth_units": "get_input:pasqualevpe0_bandwidth_units",
- "vnf_id": "123",
- "vmxvre_oam_prefix": "24",
- "availability_zone_0": "mtpocfo-kvm-az01",
- "ASN": "get_input:2017488_pasqualevpe0_ASN",
- "vmxvre_chassis_i2cid": "161",
- "vmxvpfe_name_0": "vPFEXI",
- "bandwidth": "get_input:pasqualevpe0_bandwidth",
- "availability_zone_max_count": "1",
- "vmxvre_volume_size_0": "45.0",
- "vmxvre_volume_size_1": "50.0",
- "vmxvpfe_sriov42_0_port_broadcastallow": "true",
- "vmxvre_oam_gateway": "10.0.0.10",
- "vmxvre_volume_name_1": "vREXI_FAVolume",
- "vmxvre_ore_present": "0",
- "vmxvre_volume_name_0": "vREXI_FBVolume",
- "vmxvre_type": "0",
- "vnf_instance_name": "get_input:2017488_pasqualevpe0_vnf_instance_name",
- "vmxvpfe_sriov41_0_port_unknownmulticastallow": "true",
- "oam_net_id": "b95eeb1d-d55d-4827-abb4-8ebb94941429",
- "vmx_int_ctl_len": "24",
- "vmxvpfe_sriov43_0_port_vlanstrip": "false",
- "vmxvpfe_sriov41_0_port_broadcastallow": "true",
- "vmxvre_volume_id_1": "6e86797e-03cd-4fdc-ba72-2957119c746d",
- "vmxvpfe_sriov41_0_port_vlanfilter": "4001",
- "nf_role": "Testing",
- "vmxvre_volume_id_0": "f4eacb79-f687-4e9d-b760-21847c8bb15a",
- "vmxvpfe_sriov42_0_port_unknownunicastallow": "true",
- "vmxvpfe_flavor_name": "ns.c20r16d25.v5"
- },
- "type": "VF",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "vfcInstanceGroups": {}
- }
- },
- "networks": {},
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- },
- "volumeGroupAllowed": true
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "uuid": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "invariantUuid": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "customizationUuid": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "version": "5",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "properties": {
- "minCountInstances": 1,
- "maxCountInstances": 1,
- "initialCount": 1,
- "vfModuleLabel": "PASQUALE_base_vPE_BV",
- "baseModule": true
- },
- "inputs": {},
- "volumeGroupAllowed": false
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {},
- "volumeGroupAllowed": true
- }
- },
- "volumeGroups": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1": {
- "uuid": "25284168-24bb-4698-8cb4-3f509146eca5",
- "invariantUuid": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
- "customizationUuid": "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "baseModule": false
- },
- "inputs": {
- "vnf_config_template_version": {
- "type": "string",
- "description": "VPE Software Version",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_config_template_version"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_config_template_version",
- "constraints": null,
- "required": true,
- "default": "17.2"
- },
- "bandwidth_units": {
- "type": "string",
- "description": "Units of bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth_units"
- },
- "fromInputName": "pasqualevpe0_bandwidth_units",
- "constraints": null,
- "required": true,
- "default": "Gbps"
- },
- "bandwidth": {
- "type": "string",
- "description": "Requested VPE bandwidth",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "bandwidth"
- },
- "fromInputName": "pasqualevpe0_bandwidth",
- "constraints": null,
- "required": true,
- "default": "10"
- },
- "AIC_CLLI": {
- "type": "string",
- "description": "AIC Site CLLI",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "AIC_CLLI"
- },
- "fromInputName": "2017488_pasqualevpe0_AIC_CLLI",
- "constraints": null,
- "required": true,
- "default": "ATLMY8GA"
- },
- "vnf_instance_name": {
- "type": "string",
- "description": "The hostname assigned to the vpe.",
- "entry_schema": null,
- "inputProperties": {
- "sourceType": "HEAT",
- "vfModuleLabel": "PASQUALE_vRE_BV",
- "paramName": "vnf_instance_name"
- },
- "fromInputName": "2017488_pasqualevpe0_vnf_instance_name",
- "constraints": null,
- "required": true,
- "default": "mtnj309me6"
- }
- }
- },
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2": {
- "uuid": "0a0dd9d4-31d3-4c3a-ae89-a02f383e6a9a",
- "invariantUuid": "eff8cc59-53a1-4101-aed7-8cf24ecf8339",
- "customizationUuid": "3cd946bb-50e0-40d8-96d3-c9023520b557",
- "description": null,
- "name": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "version": "6",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
- "properties": {
- "minCountInstances": 0,
- "maxCountInstances": null,
- "initialCount": 0,
- "vfModuleLabel": "PASQUALE_vPFE_BV",
- "baseModule": false
- },
- "inputs": {}
- }
- },
- "pnfs": {}
- }
- }
-
});
import {NgRedux} from "@angular-redux/store";
import {AppState} from "../../../../../shared/store/reducers";
import {DefaultDataGeneratorService} from "../../../../../shared/services/defaultDataServiceGenerator/default.data.generator.service";
-import {GenericFormPopupComponent, PopupType} from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
+import {
+ GenericFormPopupComponent,
+ PopupType
+} from "../../../../../shared/components/genericFormPopup/generic-form-popup.component";
import {DialogService} from 'ng2-bootstrap-modal';
import {VnfPopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vnf/vnf.popup.service";
import {VfModulePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModule/vfModule.popup.service";
import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
import {DuplicateService} from "../../../duplicate/duplicate.service";
import {DuplicateVnfComponent} from "../../../duplicate/duplicate-vnf.component";
-import {SdcUiServices} from "onap-ui-angular";
import {IframeService} from "../../../../../shared/utils/iframe.service";
import {changeInstanceCounter, removeInstance} from "../../../../../shared/storeUtil/utils/general/general.actions";
import {MessageBoxData} from "../../../../../shared/components/messageBox/messageBox.data";
import {MessageBoxService} from "../../../../../shared/components/messageBox/messageBox.service";
import {ServiceInstanceActions} from "../../../../../shared/models/serviceInstanceActions";
-import {deleteActionVnfInstance, undoDeleteActionVnfInstance, undoUpgradeVnf, updateVnfPosition, upgradeVnf} from "../../../../../shared/storeUtil/utils/vnf/vnf.actions";
+import {
+ deleteActionVnfInstance,
+ undoDeleteActionVnfInstance,
+ undoUpgradeVnf,
+ updateVnfPosition,
+ upgradeVnf
+} from "../../../../../shared/storeUtil/utils/vnf/vnf.actions";
import * as _ from 'lodash';
import {IModalConfig} from "onap-ui-angular/dist/modals/models/modal-config";
import {ComponentInfoType} from "../../../component-info/component-info-model";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
import {VfModuleUpgradePopupService} from "../../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
+import {ModalService} from "../../../../../shared/components/customModal/services/modal.service";
export class VnfModelInfo implements ILevelNodeInfo {
constructor(private _dynamicInputsService: DynamicInputsService,
private _vfModulePopupService: VfModulePopupService,
private _vfModuleUpgradePopupService: VfModuleUpgradePopupService,
private _duplicateService: DuplicateService,
- private modalService: SdcUiServices.ModalService,
+ private modalService: ModalService,
private _iframeService: IframeService,
private _componentInfoService: ComponentInfoService,
private _featureFlagsService: FeatureFlagsService,
* @param instance - vnf instance
* @param serviceHierarchy - serviceHierarchy
************************************************************/
- getModel = (vnfModelId: string, instance: VnfInstance, serviceHierarchy): VNFModel => {
- const originalModelName = instance.originalName ? instance.originalName : vnfModelId;
- return new VNFModel(serviceHierarchy[this.name][originalModelName], this._featureFlagsService.getAllFlags());
+ getModel = (instanceModel: any): VNFModel => {
+ return new VNFModel(
+ instanceModel,
+ this._featureFlagsService.getAllFlags());
};
-
/***********************************************************
* return vnf instance tree node
* @param instance - vnf instance
* @param model - vnf model
* @param parentModel
* @param storeKey - store key if exist
+ * @param serviceModelId
************************************************************/
- createInstanceTreeNode = (instance: VnfInstance, model: VNFModel, parentModel, storeKey: string): VnfTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let node = new VnfTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
node = this._sharedTreeService.addingStatusProperty(node);
});
}
},
- visible: (node) => this._sharedTreeService.shouldShowDelete(node),
- enable: (node) => this._sharedTreeService.shouldShowDelete(node)
+ visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
+ enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
},
undoDelete: {
method: (node, serviceModelId) => {
import {AaiService} from "../../../../../shared/services/aaiService/aai.service";
import {FeatureFlagsService} from "../../../../../shared/services/featureFlag/feature-flags.service";
import {ITableContent} from "../../../../../shared/components/searchMembersModal/members-table/element-table-row.model";
+import {VNFModel} from "../../../../../shared/models/vnfModel";
describe('VnfGroupingModelInfo Model Info', () => {
let injector;
});
test('getModel should return VnfGroup model', () => {
- let model: VnfGroupModel = vnfGroupModel.getModel('ResourceGroup0', <any>{
- originalName : 'ResourceGroup0'
- }, getServiceHierarchy());
- expect(model.type).toEqual('VnfGroup');
+ expect(vnfGroupModel.getModel({})).toBeInstanceOf(VnfGroupModel);
});
test('getMenuAction: showAuditInfoVnfGroup', ()=>{
]);
});
- function getServiceHierarchy(){
- return {
- "service": {
- "uuid": "6b528779-44a3-4472-bdff-9cd15ec93450",
- "invariantUuid": "e49fbd11-e60c-4a8e-b4bf-30fbe8f4fcc0",
- "name": "action-data",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "",
- "serviceType": "",
- "serviceRole": "",
- "description": "",
- "serviceEcompNaming": "false",
- "instantiationType": "Macro",
- "inputs": {
- "2017488_pasqualevpe0_ASN": {
- "type": "string",
- "description": "AV/PE",
- "entry_schema": null,
- "inputProperties": null,
- "constraints": [],
- "required": true,
- "default": "AV_vPE"
- }
- },
- "vidNotions": {
- "instantiationUI": "legacy",
- "modelCategory": "other"
- }
- },
- "vnfGroups": {
- "ResourceGroup0": {
- "type": "VnfGroup",
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "invariantUuid": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "version": "1",
- "name": "ResourceGroup0",
- "modelCustomizationName": "ResourceGroup0",
- "properties": {
- "contained_resource_type": "VF",
- "role": "SERVICE-ACCESS",
- "function": "DATA",
- "description": "DDD0",
- "type": "LOAD-GROUP"
- },
- "members": {
- "vdorothea_svc_vprs_proxy 0": {
- "uuid": "65fadfa8-a0d9-443f-95ad-836cd044e26c",
- "invariantUuid": "f4baae0c-b3a5-4ca1-a777-afbffe7010bc",
- "description": "A Proxy for Service vDOROTHEA_Svc_vPRS",
- "name": "vDOROTHEA_Svc_vPRS Service Proxy",
- "version": "1.0",
- "customizationUuid": "bdb63d23-e132-4ce7-af2c-a493b4cafac9",
- "inputs": {},
- "commands": {},
- "properties": {},
- "type": "Service Proxy",
- "sourceModelUuid": "da7827a2-366d-4be6-8c68-a69153c61274",
- "sourceModelInvariant": "24632e6b-584b-4f45-80d4-fefd75fd9f14",
- "sourceModelName": "vDOROTHEA_Svc_vPRS"
- },
- "vdorothea_svc_vprs_proxy 1": {
- "uuid": "111dfa8-a0d9-443f-95ad-836cd044e26c",
- "invariantUuid": "111ae0c-b3a5-4ca1-a777-afbffe7010bc",
- "description": "A Proxy for Service vDOROTHEA_Svc_vPRS",
- "name": "111_Svc_vPRS Service Proxy",
- "version": "1.0",
- "customizationUuid": "1113d23-e132-4ce7-af2c-a493b4cafac9",
- "inputs": {},
- "commands": {},
- "properties": {},
- "type": "Service Proxy",
- "sourceModelUuid": "11127a2-366d-4be6-8c68-a69153c61274",
- "sourceModelInvariant": "1112e6b-584b-4f45-80d4-fefd75fd9f14",
- "sourceModelName": "111_Svc_vPRS"
- }
- }
- }
- },
- "networks": {},
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {},
- "vfModules": {},
- "volumeGroups": {},
- "pnfs": {}
- }
- }
-
- function loadMockMembers(): any[] {
- return [
- {
- "action": "None",
- "instanceName": "VNF1_INSTANCE_NAME",
- "instanceId": "VNF1_INSTANCE_ID",
- "orchStatus": null,
- "productFamilyId": null,
- "lcpCloudRegionId": "hvf23b",
- "tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a",
- "tenantName": "APPC-24595-T-IST-02C",
- "modelInfo": {
- "modelInvariantId": "vnf-instance-model-invariant-id",
- "modelVersionId": "7a6ee536-f052-46fa-aa7e-2fca9d674c44",
- "modelVersion": "2.0",
- "modelName": "vf_vEPDG",
- "modelType": "vnf"
- },
- "instanceType": "VNF1_INSTANCE_TYPE",
- "provStatus": null,
- "inMaint": false,
- "uuid": "7a6ee536-f052-46fa-aa7e-2fca9d674c44",
- "originalName": null,
- "legacyRegion": null,
- "lineOfBusiness": null,
- "platformName": null,
- "trackById": "7a6ee536-f052-46fa-aa7e-2fca9d674c44:002",
- "serviceInstanceId": "service-instance-id1",
- "serviceInstanceName": "service-instance-name"
- },
- {
- "action": "None",
- "instanceName": "VNF2_INSTANCE_NAME",
- "instanceId": "VNF2_INSTANCE_ID",
- "orchStatus": null,
- "productFamilyId": null,
- "lcpCloudRegionId": "hvf23b",
- "tenantId": "3e9a20a3e89e45f884e09df0cc2d2d2a",
- "tenantName": "APPC-24595-T-IST-02C",
- "modelInfo": {
- "modelInvariantId": "vnf-instance-model-invariant-id",
- "modelVersionId": "eb5f56bf-5855-4e61-bd00-3e19a953bf02",
- "modelVersion": "1.0",
- "modelName": "vf_vEPDG",
- "modelType": "vnf"
- },
- "instanceType": "VNF2_INSTANCE_TYPE",
- "provStatus": null,
- "inMaint": true,
- "uuid": "eb5f56bf-5855-4e61-bd00-3e19a953bf02",
- "originalName": null,
- "legacyRegion": null,
- "lineOfBusiness": null,
- "platformName": null,
- "trackById": "eb5f56bf-5855-4e61-bd00-3e19a953bf02:003",
- "serviceInstanceId": "service-instance-id2",
- "serviceInstanceName": "service-instance-name"
- }
- ];
- }
-
});
getType = (): string => 'VnfGroup';
- createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string): any {
+ createInstanceTreeNode(instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any {
let node = new VnfGroupTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node = this._sharedTreeService.addingStatusProperty(node);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
node.limitMembers = (!_.isNil(model.properties.quantity)) ? model.properties.quantity : null;
return node;
}
- getModel(modelId: string, instance: any, serviceHierarchy): any {
- const originalModelName = instance.originalName ? instance.originalName : modelId;
- return new VnfGroupModel(serviceHierarchy[this.name][originalModelName]);
+ getModel(instanceModel: any): any {
+ return new VnfGroupModel(instanceModel);
}
hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean): boolean {
});
}
},
- visible: (node) => this._sharedTreeService.shouldShowDelete(node),
- enable: (node) => this._sharedTreeService.shouldShowDelete(node)
+ visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
+ enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
},
undoDelete: {
method: (node, serviceModelId) => {
updateDynamicInputsDataFromModel = (currentModel): any => [];
- getModel = (modelId: string, instance: any, serviceHierarchy): any => {
+ getModel = (instanceModel: any): any => {
return new Level1Model();
};
- createInstanceTreeNode = (instance: NetworkInstance, model: any, parentModel, storeKey: string): VpnTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let node = new VpnTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node = this._sharedTreeService.addingStatusProperty(node);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
node = this._sharedTreeService.addingStatusProperty(node);
let _iframeService : IframeService;
let _networkStepService : NetworkStepService;
let _vpnStepService : VpnStepService;
+ let _featureFlagsService : FeatureFlagsService;
let vrfModel: VrfModelInfo;
beforeEach(() => {
_dialogService = injector.get(DialogService);
_iframeService = injector.get(IframeService);
_networkStepService = injector.get(NetworkStepService);
+ _featureFlagsService = injector.get(FeatureFlagsService);
_vpnStepService = injector.get(VpnStepService);
_store = injector.get(NgRedux);
_componentInfoService = injector.get(ComponentInfoService);
- vrfModel = new VrfModelInfo(_store,_sharedTreeService, _dialogService, _iframeService, _networkStepService, _vpnStepService);
+ vrfModel = new VrfModelInfo(_store,_sharedTreeService, _dialogService, _iframeService, _featureFlagsService, _networkStepService, _vpnStepService);
});
test('getModel should return VRF model with min and max are equal to 1 (hard coded)', () => {
- let model: VrfModel = vrfModel.getModel('VRF Entry Configuration 0', <any>{
- originalName : 'VRF Entry Configuration 0'
- }, getServiceHierarchy());
+ let model: VrfModel = vrfModel.getModel({
+ "uuid": "9cac02be-2489-4374-888d-2863b4511a59",
+ "invariantUuid": "b67a289b-1688-496d-86e8-1583c828be0a",
+ "properties": {
+ "ecomp_generated_naming": "false",
+ "type": "VRF-ENTRY",
+ },
+ "type": "Configuration"
+ }
+ );
expect(model.properties['type']).toEqual('VRF-ENTRY');
expect(model.min).toEqual(1);
expect(model.max).toEqual(1);
};
}
- function getServiceHierarchy() {
- return {
- "service": {
- "uuid": "f028b2e2-7080-4b13-91b2-94944d4c42d8",
- "invariantUuid": "dfc2c44c-2429-44ca-ae26-1e6dc1f207fb",
- "name": "infraVPN",
- "version": "1.0",
- "toscaModelURL": null,
- "category": "Network Service",
- "serviceType": "BONDING",
- "serviceRole": "INFRASTRUCTURE-VPN",
- "description": "ddd",
- "serviceEcompNaming": "true",
- "instantiationType": "A-La-Carte",
- "inputs": {},
- "vidNotions": {
- "instantiationUI": "macroService",
- "modelCategory": "other",
- "viewEditUI": "legacy"
- }
- },
- "vnfs": {},
- "networks": {},
- "collectionResources": {},
- "configurations": {},
- "fabricConfigurations": {},
- "serviceProxies": {
- "misvpn_service_proxy 0": {
- "uuid": "35186eb0-e6b6-4fa5-86bb-1501b342a7b1",
- "invariantUuid": "73f89e21-b96c-473f-8884-8b93bcbd2f76",
- "description": "A Proxy for Service MISVPN_SERVICE",
- "name": "MISVPN_SERVICE Service Proxy",
- "version": "3.0",
- "customizationUuid": "4c2fb7e0-a0a5-4b32-b6ed-6a974e55d923",
- "inputs": {},
- "commands": {},
- "properties": {
- "ecomp_generated_naming": "false"
- },
- "type": "Service Proxy",
- "sourceModelUuid": "d5cc7d15-c842-450e-95ae-2a69e66dd23b",
- "sourceModelInvariant": "c126ec86-59fe-48c0-9532-e39a9b3e5272",
- "sourceModelName": "MISVPN_SERVICE"
- }
- },
- "vfModules": {},
- "volumeGroups": {},
- "pnfs": {},
- "vnfGroups": {},
- "vrfs": {
- "VRF Entry Configuration 0": {
- "uuid": "9cac02be-2489-4374-888d-2863b4511a59",
- "invariantUuid": "b67a289b-1688-496d-86e8-1583c828be0a",
- "description": "VRF Entry configuration object",
- "name": "VRF Entry Configuration",
- "version": "30.0",
- "customizationUuid": "dd024d73-9bd1-425d-9db5-476338d53433",
- "inputs": {},
- "commands": {},
- "properties": {
- "ecomp_generated_naming": "false",
- "type": "VRF-ENTRY",
- "role": "INFRASTRUCTURE-CLOUD-VPN"
- },
- "type": "Configuration",
- "modelCustomizationName": "VRF Entry Configuration 0",
- "sourceNodes": [],
- "collectorNodes": null,
- "configurationByPolicy": false
- }
- }
- }
- }
-
-
})
import {ITreeNode} from "angular-tree-component/dist/defs/api";
import {AvailableNodeIcons} from "../../../available-models-tree/available-models-tree.service";
import {ModelInformationItem} from "../../../../../shared/components/model-information/model-information.component";
-import {VrfInstance} from "../../../../../shared/models/vrfInstance";
import {VrfTreeNode} from "../../../../../shared/models/vrfTreeNode";
import {VrfModel} from "../../../../../shared/models/vrfModel";
import {NgRedux} from "@angular-redux/store";
updateDynamicInputsDataFromModel = (currentModel): any => [];
- getModel = (vrfModelId: string, instance: VrfInstance, serviceHierarchy): VrfModel => {
- const originalModelName = instance.originalName ? instance.originalName : vrfModelId;
- return new VrfModel(serviceHierarchy[this.name][originalModelName]);
+ getModel = (instanceModel: any): VrfModel => {
+ return new VrfModel(instanceModel);
};
- createInstanceTreeNode = (instance: VrfInstance, model: VrfModel, parentModel, storeKey: string): VrfTreeNode => {
+ createInstanceTreeNode = (instance: any, model: any, parentModel: any, storeKey: string, serviceModelId: string): any => {
let node = new VrfTreeNode(instance, model, storeKey);
node.missingData = this.hasMissingData(instance, node, model.isEcompGeneratedNaming);
node.typeName = this.typeName;
- node.menuActions = this.getMenuAction(<any>node, model.uuid);
+ node.menuActions = this.getMenuAction(<any>node, serviceModelId);
node.isFailed = _.isNil(instance.isFailed) ? false : instance.isFailed;
node.statusMessage = !_.isNil(instance.statusMessage) ? instance.statusMessage : "";
return node;
let counter: number = !_.isNil(this._store.getState().service.serviceInstance[serviceModelId]) ?
(this._store.getState().service.serviceInstance[serviceModelId].existingVRFCounterMap[node.data.modelUniqueId] || 0) : 0;
counter -= this._sharedTreeService.getExistingInstancesWithDeleteMode(node, serviceModelId, 'vrfs');
- const model = node.data.getModel(node.data.name, node.data, serviceHierarchy);
+
+ const instanceModel = this._sharedTreeService.modelByIdentifiers(
+ serviceHierarchy, node.data.modelTypeName,
+ this._sharedTreeService.modelUniqueNameOrId(node.data), node.data.name
+ );
+
+ const model = node.data.getModel(instanceModel);
const maxInstances: number = model.max;
const isReachedLimit = !(maxInstances > counter);
const showAddIcon = this._sharedTreeService.shouldShowAddIcon() && !isReachedLimit;
method: (node, serviceModelId) => {
this._store.dispatch(deleteActionVrfInstance(node.data.vrfStoreKey, serviceModelId));
},
- visible: (node) => this._sharedTreeService.shouldShowDelete(node),
- enable: (node) => this._sharedTreeService.shouldShowDelete(node)
+ visible: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId),
+ enable: (node) => this._sharedTreeService.shouldShowDelete(node, serviceModelId)
},
undoDelete: {
method: (node, serviceModelId) => {
import {VnfGroupPopupService} from "../../../../shared/components/genericFormPopup/genericFormServices/vnfGroup/vnfGroup.popup.service";
import {VnfGroupControlGenerator} from "../../../../shared/components/genericForm/formControlsServices/vnfGroupGenerator/vnfGroup.control.generator";
import {DuplicateService} from "../../duplicate/duplicate.service";
-import {SdcUiComponentsModule, SdcUiServices} from "onap-ui-angular";
+import {SdcUiComponentsModule} from "onap-ui-angular";
import {ErrorMsgService} from "../../../../shared/components/error-msg/error-msg.service";
import {ComponentInfoService} from "../../component-info/component-info.service";
import {NetworkStepService} from "../models/vrf/vrfModal/networkStep/network.step.service";
import {VpnStepService} from "../models/vrf/vrfModal/vpnStep/vpn.step.service";
import {VfModuleUpgradePopupService} from "../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
import {SharedControllersService} from "../../../../shared/components/genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../../shared/components/customModal/services/modal.service";
+import {CreateDynamicComponentService} from "../../../../shared/components/customModal/services/create-dynamic-component.service";
class MockAppStore<T> {
getState() {
DialogService,
ErrorMsgService,
ComponentInfoService,
- SdcUiServices.ModalService,
+ ModalService,
NetworkStepService,
VpnStepService,
+ ModalService,
+ CreateDynamicComponentService,
{ provide: NgRedux, useClass: MockAppStore },
MockNgRedux]
});
"tenantId": "229bcdc6eaeb4ca59d55221141d01f8e",
"platformName": "xxx1",
"lineOfBusiness": "ONAP",
- "uuid": "network-instance-model-version-id",
"routeTarget": {
"globalRouteTarget": "mock-global-1",
"routeTargetRole": "mock-role-x"
{
"action": 'None',
"modelId": "afacccf6-397d-45d6-b5ae-94c39734b168",
+ "modelInvariantId": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
"modelCustomizationId": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
"modelUniqueId": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
"missingData": true,
"inMaint": true,
"name": "2017-388_PASQUALE-vPE 0",
"modelName": "2017-388_PASQUALE-vPE 0",
+ "modelTypeName": "vnfs",
"type": "VF",
"parentType": '',
"isEcompGeneratedNaming": false,
"parentType": '',
"name": "2017-488_PASQUALE-vPE 0",
"modelName": "2017-488_PASQUALE-vPE 0",
+ "modelTypeName": "vnfs",
"type": "VF",
"isEcompGeneratedNaming": false,
"networkStoreKey": "2017-488_PASQUALE-vPE 0",
"parentType": 'VNF',
"action": 'None',
"modelId": "f8360508-3f17-4414-a2ed-6bc71161e8db",
+ "modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
"modelCustomizationId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
"modelUniqueId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
"missingData": true,
"statusMessage": "Failed vfModel message",
"name": "<Automatically Assigned>",
"modelName": "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
+ "modelTypeName": "vfModules",
"type": "VFmodule",
"isEcompGeneratedNaming": false,
"dynamicInputs": [],
"id": "o65b26t2thj",
"name": "2017488_PASQUALEvPE",
"modelName": "2017-488_PASQUALE-vPE 0",
+ "modelTypeName": "vnfs",
"type": "VF",
"isEcompGeneratedNaming": false,
"vnfStoreKey": "2017-488_PASQUALE-vPE 0",
"missingData": false,
"name": "yoav",
"modelName": "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
+ "modelTypeName": "vfModules",
"type": "VFmodule",
"isEcompGeneratedNaming": false,
"typeName": "M",
"parentType": '',
"action": 'None',
"modelId": "ddc3f20c-08b5-40fd-af72-c6d14636b986",
+ "modelInvariantId": "379f816b-a7aa-422f-be30-17114ff50b7c",
"modelCustomizationId": "94fdd893-4a36-4d70-b16a-ec29c54c184f",
"modelUniqueId": "94fdd893-4a36-4d70-b16a-ec29c54c184f",
"missingData": false,
"routeTargetRole": "mock-role-x",
"statusMessage": "Network failed message",
"modelName": "ExtVL 0",
+ "modelTypeName": "networks",
"type": "VL",
"isEcompGeneratedNaming": true,
"networkStoreKey": "ExtVL 0",
"id": "2mdxioxca9h",
"name": "<Automatically Assigned>",
"modelName": "ExtVL 0",
+ "modelTypeName": "networks",
"type": "VL",
"isEcompGeneratedNaming": true,
"networkStoreKey": "ExtVL 0:0001",
"id": "z7vd1gmpbs",
"name": "ExtVL",
"modelName": "ExtVL 0",
+ "modelTypeName": "networks",
"type": "VL",
"isEcompGeneratedNaming": true,
"networkStoreKey": "ExtVL 0_1",
import {FeatureFlagsService, Features} from "../../../../shared/services/featureFlag/feature-flags.service";
import {NgRedux} from "@angular-redux/store";
import {AppState} from "../../../../shared/store/reducers";
+import {SharedTreeService} from "../shared.tree.service";
@Injectable()
export class ObjectToInstanceTreeService {
- constructor(private _objectToTreeService: ObjectToTreeService, private _errorMsgService: ErrorMsgService, private store: NgRedux<AppState>) {
+ constructor(private _objectToTreeService: ObjectToTreeService, private _errorMsgService: ErrorMsgService,
+ private store: NgRedux<AppState>, private _sharedTreeService: SharedTreeService) {
this.numberOfFailed = 0;
this.numberOfElements = 0;
this.numberOfFailed = 0;
this.numberOfElements = 0;
let _this = this;
+ const serviceModelId:string = serviceInstance.modelInfo.modelVersionId;
const firstLevelOptions: ILevelNodeInfo[] = _this._objectToTreeService.getFirstLevelOptions();
for (let option of firstLevelOptions) {
_.forOwn(serviceInstance[option.name], function (instance, modelName) {
- nodes.push(_this.getNodeInstance(modelName, null, instance, serviceHierarchy, option));
+ nodes.push(_this.getNodeInstance(modelName, null, instance, serviceHierarchy, option, serviceModelId));
});
}
return this.sortElementsByPosition(nodes);
* @param instance
* @param serviceHierarchy - The service Hierarchy store
* @param option
+ * @param serviceModelId
* @param parentType
****************************************************************/
- getNodeInstance(modelName: string, parentModel: any, instance: any, serviceHierarchy, option: ILevelNodeInfo, parentType ?: string) {
- const model = option.getModel(modelName, instance, serviceHierarchy);
-
- let optionalNodes = option.createInstanceTreeNode(instance, model, parentModel, modelName);
+ getNodeInstance(modelName: string, parentModel: any, instance: any, serviceHierarchy, option: ILevelNodeInfo, serviceModelId: string, parentType ?: string) {
+ const instanceModel = this._sharedTreeService.modelByIdentifiers(
+ serviceHierarchy, option.name,
+ this._sharedTreeService.modelUniqueNameOrId(instance), modelName
+ );
+ const model = option.getModel(instanceModel);
+
+ let optionalNodes = option.createInstanceTreeNode(instance, model, parentModel, modelName, serviceModelId);
this.increaseNumberOfFailed(optionalNodes);
this.increaseNumberOfExcitingElements();
let nodes: any[] = _.isArray(optionalNodes) ? optionalNodes : [optionalNodes];
for (let node of nodes) {
node = this.addingExtraDataToNode(node, modelName, parentModel, instance, serviceHierarchy, option, parentType);
- let children = this.addNextInstanceTreeNode(instance, model, option, node, serviceHierarchy);
+ let children = this.addNextInstanceTreeNode(instance, model, option, node, serviceHierarchy, serviceModelId);
if (!_.isNil(children) && children.length > 0) {
node.children = this.sortElementsByPosition(children);
}
node.parentType = !_.isNil(parentType) ? parentType : "";
node.updatePoistionFunction = option.updatePosition;
node.position = option.getNodePosition(instance, node.dynamicModelName);
+ node.modelTypeName = option.name;
node.getModel = option.getModel.bind(option);
node.getInfo = !_.isNil(option.getInfo) ? option.getInfo.bind(option) : ()=>{};
node.componentInfoType = option.componentInfoType;
* @param levelNodeInfo
* @param parentNode
* @param serviceHierarchy - The service Hierarchy store
+ * @param serviceModelId
****************************************************************/
- addNextInstanceTreeNode(parentInstance, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode, serviceHierarchy): any[] {
+ addNextInstanceTreeNode(parentInstance, parentModel, levelNodeInfo: ILevelNodeInfo, parentNode, serviceHierarchy, serviceModelId: string): any[] {
if (!_.isNil(levelNodeInfo.childNames)&& levelNodeInfo.childNames.length > 0) {
const that = this;
parentNode.children = [];
let nextLevelNodeInfo = levelNodeInfo.getNextLevelObject.apply(that, [childName]);
Object.keys(parentInstance[childName]).map((modelName) => {
let nextLevelInstance = parentInstance[childName][modelName];
- let nodes: any[] | any = that.getNodeInstance(modelName, parentModel, nextLevelInstance, serviceHierarchy, nextLevelNodeInfo, parentType);
+ let nodes: any[] | any = that.getNodeInstance(modelName, parentModel, nextLevelInstance, serviceHierarchy, nextLevelNodeInfo, serviceModelId, parentType);
if (_.isArray(nodes)) {
parentNode.children = parentNode.children.concat(nodes);
} else {
import {NetworkStepService} from "../models/vrf/vrfModal/networkStep/network.step.service";
import {VfModuleUpgradePopupService} from "../../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
import {SharedControllersService} from "../../../../shared/components/genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../../shared/components/customModal/services/modal.service";
+import {CreateDynamicComponentService} from "../../../../shared/components/customModal/services/create-dynamic-component.service";
class MockAppStore<T> {
getState() {
ComponentInfoService,
NetworkStepService,
VpnStepService,
+ ModalService,
+ CreateDynamicComponentService,
SharedControllersService,
{provide: NgRedux, useClass: MockAppStore},
MockNgRedux ]
"name": "2017-388_PASQUALE-vPE 1",
"tooltip": "VF",
"type": "VF",
+ "modelTypeName": "vnfs",
"count": 0,
"max": 1,
"children": [],
"name": "2017-388_PASQUALE-vPE 0",
"tooltip": "VF",
"type": "VF",
+ "modelTypeName": "vnfs",
"count": 0,
"max": 1,
"children": [],
"name": "2017-488_PASQUALE-vPE 0",
"tooltip": "VF",
"type": "VF",
+ "modelTypeName": "vnfs",
"count": 0,
"max": 1,
"children": [{
"name": "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1",
"tooltip": "VFmodule",
"type": "VFmodule",
+ "modelTypeName": "vfModules",
"count": 0,
"max": 1,
"children": [],
"name": "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
"tooltip": "VFmodule",
"type": "VFmodule",
+ "modelTypeName": "vfModules",
"count": 0,
"max": 1,
"children": [],
"name": "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vPFE_BV..module-2",
"tooltip": "VFmodule",
"type": "VFmodule",
+ "modelTypeName": "vfModules",
"count": 0,
"max": 1,
"children": [],
node.getNodeCount = (node, serviceId) => levelNodeInfo.getNodeCount(node, serviceId);
node.getMenuAction = (node, serviceId) => levelNodeInfo.getMenuAction(node, serviceId);
node.showNodeIcons = (node, serviceId) => levelNodeInfo.showNodeIcons(node, serviceId);
- node.typeName = levelNodeInfo.typeName;
node.getModel = levelNodeInfo.getModel.bind(levelNodeInfo);
- node.getInfo = !_.isNil(levelNodeInfo.getInfo) ? levelNodeInfo.getInfo.bind(levelNodeInfo) : () => {
- };
+ node.getInfo = !_.isNil(levelNodeInfo.getInfo) ? levelNodeInfo.getInfo.bind(levelNodeInfo) : () => {};
node.componentInfoType = levelNodeInfo.componentInfoType;
+ node.typeName = levelNodeInfo.typeName;
+ node.modelTypeName = levelNodeInfo.name;
return node;
}
}
import {VnfGroupingModelInfo} from "./models/vnfGrouping/vnfGrouping.model.info";
import {VnfGroupPopupService} from "../../../shared/components/genericFormPopup/genericFormServices/vnfGroup/vnfGroup.popup.service";
import {DuplicateService} from "../duplicate/duplicate.service";
-import {SdcUiServices} from "onap-ui-angular";
import {IframeService} from "../../../shared/utils/iframe.service";
import {ComponentInfoService} from "../component-info/component-info.service";
import {PnfModelInfo} from "./models/pnf/pnf.model.info";
import {VrfModelInfo} from "./models/vrf/vrf.model.info";
import {NetworkStepService} from "./models/vrf/vrfModal/networkStep/network.step.service";
import {VpnStepService} from "./models/vrf/vrfModal/vpnStep/vpn.step.service";
-import { VfModuleUpgradePopupService } from "../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
+import {VfModuleUpgradePopupService} from "../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
import {FeatureFlagsService} from "../../../shared/services/featureFlag/feature-flags.service";
+import {ModalService} from "../../../shared/components/customModal/services/modal.service";
@Injectable()
export class ObjectToTreeService {
private _vfModuleUpgradePopupService : VfModuleUpgradePopupService,
private _vnfGroupPopupService : VnfGroupPopupService,
private _duplicateService : DuplicateService,
- private _modalService: SdcUiServices.ModalService,
+ private _modalService: ModalService,
private _iframeService : IframeService,
private _componentInfoService : ComponentInfoService,
private _networkStepService : NetworkStepService,
}
-
-
/***********************************************************
* return all first optional first level of the model tree
************************************************************/
getFirstLevelOptions(): ILevelNodeInfo[] {
return [new VnfModelInfo(this._dynamicInputsService, this._sharedTreeService, this._defaultDataGeneratorService, this._dialogService, this._vnfPopupService, this._vfModulePopupService, this._vfModuleUpgradePopupService,this._duplicateService, this._modalService, this._iframeService, this._componentInfoService, this._featureFlagsService, this._store)
, new NetworkModelInfo(this._dynamicInputsService, this._sharedTreeService, this._dialogService, this._networkPopupService, this._duplicateService, this._modalService, this._iframeService, this._featureFlagsService, this._store),
- new PnfModelInfo(),
+ new PnfModelInfo(this._sharedTreeService),
new VrfModelInfo(this._store, this._sharedTreeService, this._dialogService, this._iframeService, this._featureFlagsService, this._networkStepService, this._vpnStepService),
new CollectionResourceModelInfo(this._store, this._sharedTreeService),
new ConfigurationModelInfo(this._dynamicInputsService, this._sharedTreeService),
import {NetworkStepService} from "./models/vrf/vrfModal/networkStep/network.step.service";
import {VfModuleUpgradePopupService} from "../../../shared/components/genericFormPopup/genericFormServices/vfModuleUpgrade/vfModule.upgrade.popuop.service";
import {SharedControllersService} from "../../../shared/components/genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../shared/components/customModal/services/modal.service";
+import {CreateDynamicComponentService} from "../../../shared/components/customModal/services/create-dynamic-component.service";
class MockAppStore<T> {
getState() {
};
nodeData['menuActions'][menuAction] = {
method: (node, serviceModelId) => {}
- }
+ };
const node = {
parent: {
data: nodeData,
ComponentInfoService,
NetworkStepService,
VpnStepService,
+ ModalService,
+ CreateDynamicComponentService,
{provide: NgRedux, useClass: MockAppStore}
]
});
test('SharedTreeService upgradeBottomUp should call redux actions', () => {
const serviceModelId = "1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd";
- const node = getNodeWithData("upgrade")
+ const node = getNodeWithData("upgrade");
spyOn(node.parent.data.menuActions['upgrade'], 'method');
service.upgradeBottomUp(node, serviceModelId);
expect(node.parent.data.menuActions['upgrade'].method).toBeCalledWith(node.parent, serviceModelId);
test('SharedTreeService undoUpgradeBottomUp should call redux actions', () => {
const serviceModelId = "1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd";
- const node = getNodeWithData("undoUpgrade")
+ const node = getNodeWithData("undoUpgrade");
spyOn(node.parent.data.menuActions['undoUpgrade'], 'method');
service.undoUpgradeBottomUp(node, serviceModelId);
expect(node.parent.data.menuActions['undoUpgrade'].method).toBeCalledWith(node.parent, serviceModelId);
expect(MessageBoxService.openModal.next).toHaveBeenCalled();
});
- test('openAuditInfoModal should open modal for failed instance', () => {
+ each([
+ ['volumeGroups by entry name', "volumeGroups",
+ "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_vRE_BV..module-1", "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1"],
+ ['vfmodule by customizationUuid', "vfModules",
+ "f7e7c365-60cf-49a9-9ebf-a1aa11b9d401", "2017488PasqualeVpe..PASQUALE_vRE_BV..module-1"],
+ ['vnf by customizationUuid', "vnfs",
+ "1da7b585-5e61-4993-b95e-8e6606c81e45", "2017-488_PASQUALE-vPE 0"],
+ ['vnfGroups by invariantUuid because no customizationUuid', "vnfGroups",
+ "4bb2e27e-ddab-4790-9c6d-1f731bc14a45", "groupingservicefortest..ResourceInstanceGroup..0"],
+ ]).test('modelByIdentifier should success: %s', (description, modelTypeName, modelUniqueIdOrName, expectedModelCustomizationName) => {
+ let serviceModelFromHierarchy =
+ getStore().service.serviceHierarchy["1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd"];
+
+ expect(service.modelByIdentifiers(serviceModelFromHierarchy, modelTypeName, modelUniqueIdOrName))
+ .toHaveProperty("modelCustomizationName", expectedModelCustomizationName);
+ });
+
+ each([
+ ['vfmodule by invariantUuid when there is customizationUuid', "vfModules", "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1"],
+ ['network by non-existing modelUniqueIdOrName', "networks", "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1"],
+ ['collectionResource has no resource', "collectionResources", "whatever"],
+ ['non-existing model-type', "fooBar", "whatever"],
+ ]).test('modelByIdentifier should fail: %s', (description, modelTypeName, modelUniqueIdOrName) => {
+ let serviceModelFromHierarchy =
+ getStore().service.serviceHierarchy["1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd"];
+
+ expect(service.modelByIdentifiers(serviceModelFromHierarchy, modelTypeName, modelUniqueIdOrName))
+ .toBeUndefined();
+ });
+
+ test('openAuditInfoModalInsideIframe should open modal for failed instance', () => {
jest.spyOn(AuditInfoModalComponent.openInstanceAuditInfoModal, 'next');
let modelInfoServiceMock: ILevelNodeInfo = new VnfModelInfo(null, null,
});
-
test('statusProperties should be prop on node according to node properties', () => {
let node = service.addingStatusProperty({orchStatus: 'completed', provStatus: 'inProgress', inMaint: false});
expect(node.statusProperties).toBeDefined();
testId: 'inMaint'
})]);
});
+
+ each([
+ [false, 'method is not in menu actions', ServiceInstanceActions.None, DrawingBoardModes.EDIT, {}, true],
+ [false, 'there is no action in node', null, DrawingBoardModes.EDIT, {someMethod: "someValue"}, true],
+ [true, 'edit mode, action is none, method in menu action', ServiceInstanceActions.None, DrawingBoardModes.EDIT, {someMethod: "someValue"}, true],
+ [false, 'edit mode, action is none, method in menu action, macro service', ServiceInstanceActions.None, DrawingBoardModes.EDIT, {someMethod: "someValue"}, false],
+ [false, 'edit mode, action is not none, method in menu action', ServiceInstanceActions.Resume, DrawingBoardModes.EDIT, {someMethod: "someValue"}, true],
+ [false, 'edit mode, action is CREATE, method in menu action', ServiceInstanceActions.Resume, DrawingBoardModes.EDIT, {someMethod: "someValue"}, true]
+ ]).test('shouldShowButtonGeneric return %s if %s ', (expected, description, action, mode, menuActions, isALaCarte) => {
+ jest.spyOn(store, 'getState').mockReturnValue(<any>{
+ global: {
+ drawingBoardStatus: mode
+ },
+ service : {
+ serviceInstance: {
+ someModelId : {
+ isALaCarte
+ }
+ }
+
+ }
+ });
+ let node = <any>{
+ data:{
+ action: action,
+ menuActions: menuActions
+ },
+ };
+
+ let res = service.shouldShowButtonGeneric(node, "someMethod", "someModelId");
+ expect(res).toBe(expected);
+ });
+
const enableRemoveAndEditItemsDataProvider = [
['Create action CREATE mode', DrawingBoardModes.CREATE ,ServiceInstanceActions.Create, true],
['Create action VIEW mode',DrawingBoardModes.VIEW , ServiceInstanceActions.Create,false],
let res = service.shouldShowRemoveAndEdit(node);
expect(res).toBe(enabled);
});
-});
-function generateService() {
- return {
- "vnfs": {
- "2017-488_PASQUALE-vPE 0": {
- "inMaint": false,
- "rollbackOnFailure": "true",
- "originalName": "2017-488_PASQUALE-vPE 0",
- "isMissingData": false,
- "trackById": "stigekyxrqi",
- "vfModules": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0": {
- "2017488_pasqualevpe0..2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0gytfi": {
- "isMissingData": false,
- "sdncPreReload": null,
- "modelInfo": {
- "modelType": "VFmodule",
- "modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
- "modelVersionId": "f8360508-3f17-4414-a2ed-6bc71161e8db",
- "modelName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0",
- "modelVersion": "5",
- "modelCustomizationId": "a55961b2-2065-4ab0-a5b7-2fcee1c227e3",
- "modelCustomizationName": "2017488PasqualeVpe..PASQUALE_base_vPE_BV..module-0"
- },
- "instanceParams": [{}],
- "trackById": "3oj23o7nupo"
+
+
+ const isVfmoduleAlmostPartOfModelOnlyCustomizationUuidDifferProvider = [
+ ['node is part of model, but vfmodule diff by customization',
+ true, 'mDNS 01222020 0', '9fdc68e9-9f53-431c-b8a2-7e337b9a0d0a', '82160e6e-d9c4-45ef-bd19-01573ab11b61'],
+
+ ['vnf model-name not found',
+ false, 'mDNS 01222020 1', '9fdc68e9-9f53-431c-b8a2-7e337b9a0d0a', '82160e6e-d9c4-45ef-bd19-01573ab11b61'],
+
+ ['vfmodule invariant-id not found',
+ false, 'mDNS 01222020 0', 'wrong invariant-id', '82160e6e-d9c4-45ef-bd19-01573ab11b61'],
+
+ ['vfmodule customization-id match',
+ false, 'mDNS 01222020 0', '9fdc68e9-9f53-431c-b8a2-7e337b9a0d0a', 'c9b32003-febc-44e0-a97f-7630fa7fa4a0'],
+ ];
+
+ each(isVfmoduleAlmostPartOfModelOnlyCustomizationUuidDifferProvider).test('isVfmoduleAlmostPartOfModelOnlyCustomizationUuidDiffer: when %s should return %s', (description, expected, vnfModelName, invariantUuid, customizationUuid) => {
+ const serviceModelId : string = 'a243da28-c11e-45a8-9f26-0284a9a789bc';
+ spyOn(store, 'getState').and.returnValue({
+ service : {
+ serviceHierarchy : {
+ [serviceModelId] : {
+ vnfs : {
+ [vnfModelName] : {
+ vfModules : {
+ vfModuleModelName : {
+ invariantUuid : invariantUuid,
+ customizationUuid : customizationUuid
+ }
+ }
+ }
}
}
- },
- "vnfStoreKey": "2017-488_PASQUALE-vPE 0",
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "productFamilyId": "d8a6ed93-251c-47ca-adc9-86671fd19f4c",
- "lcpCloudRegionId": "AAIAIC25",
- "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "lineOfBusiness": "ONAP",
- "platformName": "xxx1",
- "modelInfo": {
- "modelInvariantId": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "modelVersionId": "69e09f68-8b63-4cc9-b9ff-860960b5db09",
- "modelName": "2017-488_PASQUALE-vPE",
- "modelVersion": "5.0",
- "modelCustomizationName": "2017-488_PASQUALE-vPE 0",
- "modelCustomizationId": "1da7b585-5e61-4993-b95e-8e6606c81e45",
- "uuid": "69e09f68-8b63-4cc9-b9ff-860960b5db09"
- },
- "legacyRegion": "11111111",
- "instanceParams": [{}]
- },
- "2017-388_PASQUALE-vPE 0": {
- "inMaint": false,
- "rollbackOnFailure": "true",
- "originalName": "2017-388_PASQUALE-vPE 0",
- "isMissingData": false,
- "trackById": "nib719t5vca",
- "vfModules": {},
- "vnfStoreKey": "2017-388_PASQUALE-vPE 0",
- "productFamilyId": "d8a6ed93-251c-47ca-adc9-86671fd19f4c",
- "lcpCloudRegionId": "AAIAIC25",
- "legacyRegion": "11111",
- "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "platformName": "platform",
- "lineOfBusiness": "zzz1",
- "instanceParams": [{}],
- "modelInfo": {
- "modelInvariantId": "72e465fe-71b1-4e7b-b5ed-9496118ff7a8",
- "modelVersionId": "afacccf6-397d-45d6-b5ae-94c39734b168",
- "modelName": "2017-388_PASQUALE-vPE",
- "modelVersion": "4.0",
- "modelCustomizationId": "b3c76f73-eeb5-4fb6-9d31-72a889f1811c",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 0",
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168"
- },
- "uuid": "afacccf6-397d-45d6-b5ae-94c39734b168"
- },
- "2017-388_PASQUALE-vPE 1": {
- "inMaint": false,
- "rollbackOnFailure": "true",
- "originalName": "2017-388_PASQUALE-vPE 1",
- "isMissingData": false,
- "trackById": "cv7l1ak8vpe",
- "vfModules": {},
- "vnfStoreKey": "2017-388_PASQUALE-vPE 1",
- "productFamilyId": "d8a6ed93-251c-47ca-adc9-86671fd19f4c",
- "lcpCloudRegionId": "AAIAIC25",
- "legacyRegion": "123",
- "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "platformName": "platform",
- "lineOfBusiness": "ONAP",
- "instanceParams": [{}],
- "modelInfo": {
- "modelInvariantId": "00beb8f9-6d39-452f-816d-c709b9cbb87d",
- "modelVersionId": "0903e1c0-8e03-4936-b5c2-260653b96413",
- "modelName": "2017-388_PASQUALE-vPE",
- "modelVersion": "1.0",
- "modelCustomizationId": "280dec31-f16d-488b-9668-4aae55d6648a",
- "modelCustomizationName": "2017-388_PASQUALE-vPE 1",
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413"
- },
- "uuid": "0903e1c0-8e03-4936-b5c2-260653b96413"
- }
- },
- "instanceParams": [{}],
- "validationCounter": 0,
- "existingNames": {"yoav": ""},
- "existingVNFCounterMap": {
- "69e09f68-8b63-4cc9-b9ff-860960b5db09": 1,
- "afacccf6-397d-45d6-b5ae-94c39734b168": 1,
- "0903e1c0-8e03-4936-b5c2-260653b96413": 1
- },
- "existingVnfGroupCounterMap": {
- "daeb6568-cef8-417f-9075-ed259ce59f48": 0,
- "c2b300e6-45de-4e5e-abda-3032bee2de56": -1
- },
- "existingNetworksCounterMap": {"ddc3f20c-08b5-40fd-af72-c6d14636b986": 1},
- "networks": {
- "ExtVL 0": {
- "inMaint": false,
- "rollbackOnFailure": "true",
- "originalName": "ExtVL 0",
- "isMissingData": false,
- "trackById": "s6okajvv2n8",
- "networkStoreKey": "ExtVL 0",
- "productFamilyId": "d8a6ed93-251c-47ca-adc9-86671fd19f4c",
- "lcpCloudRegionId": "AAIAIC25",
- "legacyRegion": "12355555",
- "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "platformName": "platform",
- "lineOfBusiness": null,
- "instanceParams": [{}],
- "modelInfo": {
- "modelInvariantId": "379f816b-a7aa-422f-be30-17114ff50b7c",
- "modelVersionId": "ddc3f20c-08b5-40fd-af72-c6d14636b986",
- "modelName": "ExtVL",
- "modelVersion": "37.0",
- "modelCustomizationId": "94fdd893-4a36-4d70-b16a-ec29c54c184f",
- "modelCustomizationName": "ExtVL 0",
- "uuid": "ddc3f20c-08b5-40fd-af72-c6d14636b986"
- },
- "uuid": "ddc3f20c-08b5-40fd-af72-c6d14636b986"
+ }
}
- },
- "vnfGroups": {
- "groupingservicefortest..ResourceInstanceGroup..0": {
- "inMaint": false,
- "rollbackOnFailure": "true",
- "originalName": "groupingservicefortest..ResourceInstanceGroup..0",
- "isMissingData": false,
- "trackById": "se0obn93qq",
- "vnfGroupStoreKey": "groupingservicefortest..ResourceInstanceGroup..0",
- "instanceName": "groupingservicefortestResourceInstanceGroup0",
- "instanceParams": [{}],
- "modelInfo": {
- "modelInvariantId": "4bb2e27e-ddab-4790-9c6d-1f731bc14a45",
- "modelVersionId": "daeb6568-cef8-417f-9075-ed259ce59f48",
- "modelName": "groupingservicefortest..ResourceInstanceGroup..0",
- "modelVersion": "1",
- "modelCustomizationName": "groupingservicefortest..ResourceInstanceGroup..0",
- "uuid": "daeb6568-cef8-417f-9075-ed259ce59f48"
- },
- "uuid": "daeb6568-cef8-417f-9075-ed259ce59f48"
+ });
+
+ const node = <any>{
+ data:{
+ modelInvariantId : '9fdc68e9-9f53-431c-b8a2-7e337b9a0d0a',
+ modelCustomizationId : 'c9b32003-febc-44e0-a97f-7630fa7fa4a0',
+ modelName : 'vfModuleModelName'
+ },
+ parent : {
+ data : {
+ modelName : "mDNS 01222020 0"
+ }
}
- },
- "instanceName": "yoav",
- "globalSubscriberId": "e433710f-9217-458d-a79d-1c7aff376d89",
- "subscriptionServiceType": "TYLER SILVIA",
- "owningEntityId": "d61e6f2d-12fa-4cc2-91df-7c244011d6fc",
- "productFamilyId": "d8a6ed93-251c-47ca-adc9-86671fd19f4c",
- "lcpCloudRegionId": "AAIAIC25",
- "tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
- "aicZoneId": "ATL53",
- "pause": null,
- "projectName": "WATKINS",
- "rollbackOnFailure": "true",
- "bulkSize": 1,
- "aicZoneName": "AAIATLTE-ATL53",
- "owningEntityName": "WayneHolland",
- "testApi": "VNF_API",
- "isEcompGeneratedNaming": false,
- "tenantName": "USP-SIP-IC-24335-T-01",
- "modelInfo": {
- "modelInvariantId": "cdb90b57-ed78-4d44-a5b4-7f43a02ec632",
- "modelVersionId": "1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd",
- "modelName": "action-data",
- "modelVersion": "1.0",
- "uuid": "1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd"
- },
- "isALaCarte": false,
- "name": "action-data",
- "version": "1.0",
- "description": "PASQUALE vMX vPE based on Juniper 17.2 release. Updated with updated VF for v8.0 of VLM",
- "category": "Network L1-3",
- "uuid": "1a80c596-27e5-4ca9-b5bb-e03a7fd4c0fd",
- "invariantUuid": "cdb90b57-ed78-4d44-a5b4-7f43a02ec632",
- "serviceType": "pnf",
- "serviceRole": "Testing",
- "vidNotions": {"instantiationUI": "legacy", "modelCategory": "other", "viewEditUI": "legacy"},
- "isMultiStepDesign": true
- };
-}
+ };
+
+ const isDiffCustomizationUuidResponse : boolean = service.isVfmoduleAlmostPartOfModelOnlyCustomizationUuidDiffer(node, serviceModelId);
+ expect(isDiffCustomizationUuidResponse).toEqual(expected);
+ });
+
+});
function getStore() {
return {
@Injectable()
export class SharedTreeService {
- private _sharedTreeService: SharedTreeService;
constructor(private _store: NgRedux<AppState>) {
}
: (nodeInstance.modelInfo.modelCustomizationId || nodeInstance.modelInfo.modelInvariantId);
};
+ modelUniqueNameOrId = (instance): string => {
+ if (_.isNil(instance)) {
+ return null;
+ }
+
+ const innerInstance = _.find(instance) || {};
+
+ return instance.originalName
+ || this.modelUniqueId(instance)
+ || innerInstance.originalName
+ || this.modelUniqueId(innerInstance);
+ };
+
+ /**
+ * Finds a model inside a full service model
+ * @param serviceModelFromHierarchy
+ * @param modelTypeName "vnfs" | "networks" | "vfModules" | "collectionResources" | ...
+ * @param modelUniqueNameOrId Either an entry name (i.e. "originalName"), modelCustomizationId or modelInvariantId.
+ * Note that modelInvariantId will work only where model lacks a modelCustomizationId.
+ * @param modelName An optional entry name (i.e. "originalName"); will not try to use as id
+ */
+ modelByIdentifiers = (serviceModelFromHierarchy, modelTypeName: string, modelUniqueNameOrId: string, modelName?: string): any => {
+ const logErrorAndReturnUndefined = () =>
+ console.info(`modelByIdentifiers: could not find a model matching query`, {
+ modelTypeName, modelUniqueNameOrId, modelName, serviceModelFromHierarchy
+ });
+
+ if (_.isNil(serviceModelFromHierarchy)) return logErrorAndReturnUndefined();
+
+ const modelsOfType = serviceModelFromHierarchy[modelTypeName];
+ if (_.isNil(modelsOfType)) return logErrorAndReturnUndefined();
+
+ const modelIfModelIdentifierIsEntryName = modelsOfType[modelUniqueNameOrId];
+ const modelIfModeNameExists = _.isNil(modelName) ? null : modelsOfType[modelName];
+
+ if (!_.isNil(modelIfModelIdentifierIsEntryName)) {
+ return modelIfModelIdentifierIsEntryName;
+ } else if (!_.isNil(modelIfModeNameExists)) {
+ return modelIfModeNameExists;
+ } else {
+ // try modelUniqueNameOrId as an id
+ return _.find(modelsOfType, o => (o.customizationUuid || o.invariantUuid) === modelUniqueNameOrId) || logErrorAndReturnUndefined()
+ }
+ };
+
hasMissingData(instance, dynamicInputs: any, isEcompGeneratedNaming: boolean, requiredFields: string[]): boolean {
if (!isEcompGeneratedNaming && _.isEmpty(instance.instanceName)) {
return true;
/**********************************************
* should return true if can delete
**********************************************/
- shouldShowDelete(node): boolean {
- return this.shouldShowButtonGeneric(node, "delete")
+ shouldShowDelete(node, serviceModelId): boolean {
+ return this.shouldShowButtonGeneric(node, "delete", serviceModelId)
}
/**********************************************
****************************************************/
shouldShowUpgrade(node, serviceModelId): boolean {
if (FeatureFlagsService.getFlagState(Features.FLAG_FLASH_REPLACE_VF_MODULE, this._store) &&
- this.isThereAnUpdatedLatestVersion(serviceModelId)) {
- return this.shouldShowButtonGeneric(node, VNFMethods.UPGRADE);
+ (this.isThereAnUpdatedLatestVersion(serviceModelId)) || this.isVfmoduleAlmostPartOfModelOnlyCustomizationUuidDiffer(node, serviceModelId)) {
+ return this.shouldShowButtonGeneric(node, VNFMethods.UPGRADE, serviceModelId);
}
else {
return false
}
}
- private isThereAnUpdatedLatestVersion(serviceModelId) : boolean{
- let serviceInstance = this._store.getState().service.serviceInstance[serviceModelId];
+
+ isVfmoduleAlmostPartOfModelOnlyCustomizationUuidDiffer(vfModuleNode, serviceModelId) : boolean {
+ /*
+ for `true`, should all:
+ 1. parent vnf found by model-mane
+ 2. vfmodule found by invariant
+ 3. vfmodule diff by customization
+ */
+
+ if (_.isNil(vfModuleNode.data)) {
+ return false;
+ }
+
+ const vnfHierarchy = this.getParentVnfHierarchy(vfModuleNode, serviceModelId);
+ if (_.isNil(vnfHierarchy)) {
+ return false;
+ }
+
+ const vfModuleHierarchyByInvariantId = this.getVfModuleHFromVnfHierarchyByInvariantId(vfModuleNode, vnfHierarchy);
+ if(_.isNil(vfModuleHierarchyByInvariantId)){
+ return false;
+ }
+
+ return vfModuleHierarchyByInvariantId.customizationUuid
+ && (vfModuleHierarchyByInvariantId.customizationUuid !== vfModuleNode.data.modelCustomizationId);
+ }
+
+ getParentVnfHierarchy(vfModuleNode, serviceModelId) {
+ if (vfModuleNode.parent && vfModuleNode.parent.data) {
+ return this._store.getState().service.serviceHierarchy[serviceModelId].vnfs[vfModuleNode.parent.data.modelName];
+ } else {
+ return null;
+ }
+ }
+
+ getVfModuleHFromVnfHierarchyByInvariantId(vfModuleNode, parentVnfHierarchy) {
+ if(vfModuleNode.data.modelInvariantId && parentVnfHierarchy && parentVnfHierarchy.vfModules){
+ return _.find(parentVnfHierarchy.vfModules, o => o.invariantUuid === vfModuleNode.data.modelInvariantId);
+ }
+ return null;
+ }
+
+
+ isThereAnUpdatedLatestVersion(serviceModelId) : boolean{
+ let serviceInstance = this.getServiceInstance(serviceModelId);
return !_.isNil(serviceInstance.latestAvailableVersion) && (Number(serviceInstance.modelInfo.modelVersion) < serviceInstance.latestAvailableVersion);
}
- private shouldShowButtonGeneric(node, method) {
+ private getServiceInstance(serviceModelId): any {
+ return this._store.getState().service.serviceInstance[serviceModelId];
+ }
+
+ shouldShowButtonGeneric(node, method, serviceModelId) {
const mode = this._store.getState().global.drawingBoardStatus;
+ const isMacro = !(this.getServiceInstance(serviceModelId).isALaCarte);
+
+ if (isMacro) { //if macro action allowed only for service level
+ return false;
+ }
+
if (!_.isNil(node) && !_.isNil(node.data) && !_.isNil(node.data.action) && !_.isNil(node.data.menuActions[method])) {
if (mode !== DrawingBoardModes.EDIT || node.data.action === ServiceInstanceActions.Create) {
return false;
************************************************/
getExistingInstancesWithDeleteMode(node, serviceModelId: string, type: string): number {
let counter = 0;
- const existingInstances = this._store.getState().service.serviceInstance[serviceModelId][type];
+ const existingInstances = this.getServiceInstance(serviceModelId)[type];
const modelUniqueId = node.data.modelUniqueId;
if (!_.isNil(existingInstances)) {
for (let instanceKey in existingInstances) {
AuditInfoModalComponent.openInstanceAuditInfoModal.next({
instanceId: serviceModelId,
type: instanceType,
- model: modelInfoService.getModel(node.data.modelName, instance, this._store.getState().service.serviceHierarchy[serviceModelId]),
+ model: modelInfoService.getModel(
+ this.modelByIdentifiers(
+ this._store.getState().service.serviceHierarchy[serviceModelId],
+ modelInfoService.name,
+ this.modelUniqueNameOrId(instance), node.data.modelName
+ )
+ ),
instance
});
}
}
pageMode: DrawingBoardModes = DrawingBoardModes.CREATE;
- @ViewChild(DrawingBoardTreeComponent) drawingModelTree;
- @ViewChild(AvailableModelsTreeComponent) availableModelTree;
+ @ViewChild(DrawingBoardTreeComponent, {static: false}) drawingModelTree;
+ @ViewChild(AvailableModelsTreeComponent, {static: false}) availableModelTree;
isShowTree(): boolean {
return true;
<td class="mediumTd" id="created"><custom-ellipsis [id]="data.created" [value]="data.created | date:'MMM. dd, yyyy HH:mm'"></custom-ellipsis></td>
<td class="last" id="jobStatus" [ngClass]="data.jobStatus">
<custom-popover [value]="data.serviceStatus.tooltip" [popoverType]="data?.serviceStatus?.color" style="float: left;">
- <svg-icon
+ <custom-icon
id="jobStatusIcon-{{i}}"
(click)="auditInfo(data)"
[mode]="data.serviceStatus.color"
[size]="'large'"
[name]="data.serviceStatus.iconClassName">
- </svg-icon>
+ </custom-icon>
</custom-popover>
<div class="menu-div" (click)="onContextMenu($event, data)" [attr.data-tests-id]="'menu-'+data.jobId">
instantiationStatusComponentService: InstantiationStatusComponentService;
configurationService : ConfigurationService;
serviceInfoData: ServiceInfoModel[] = null;
- @ViewChild(ContextMenuComponent) public contextMenu: ContextMenuComponent;
+ @ViewChild(ContextMenuComponent, {static: false}) public contextMenu: ContextMenuComponent;
public contextMenuActions: Array<MenuAction> = [
{
</div>
</div>
<div class="col-md-8 right-panel">
- <div class="row" *ngIf="showVidStatus"><span class="table-title">VID status</span></div>
+ <div class="row" *ngIf="showVidStatus">
+ <div class="col-md-6 leftColumn"><span class="table-title">VID status</span></div>
+ <div class="col-md-6 rightColumn"><span *ngIf="showMoreAuditInfoLink">
+ <a id="full_screen_link" target="_parent" title="Full-screen audit info" [href]="readOnlyRetryUrl()">
+ <i class="fa fa-external-link"></i>
+ </a>
+ </span></div>
+ </div>
<div class="row" *ngIf="showVidStatus">
<table id="service-instantiation-audit-info-vid" class="table table-bordered">
<thead class="thead-dark">
import {NgRedux} from "@angular-redux/store";
import {AppState} from "../../store/reducers";
import {AuditInfoModalComponentService} from "./auditInfoModal.component.service";
+import {FeatureFlagsService, Features} from "../../services/featureFlag/feature-flags.service";
@Component({
selector: 'audit-info-modal',
export class AuditInfoModalComponent {
static openModal: Subject<ServiceInfoModel> = new Subject<ServiceInfoModel>();
static openInstanceAuditInfoModal: Subject<{instanceId , type, model, instance}> = new Subject<{instanceId , type, model, instance}>();
- @ViewChild('auditInfoModal') public auditInfoModal: ModalDirective;
+ @ViewChild('auditInfoModal', {static: false}) public auditInfoModal: ModalDirective;
title: string = 'Service Instantiation Information';
modelInfoItems: ModelInformationItem[] = [];
serviceModel: ServiceModel;
serviceModelName: string;
+ serviceModelId: string;
+ jobId: string;
vidInfoData: AuditStatus[] = [];
msoInfoData: AuditStatus[] = [];
isAlaCarte: boolean;
model: any;
instanceId: string;
isALaCarteFlagOn: boolean;
+ showMoreAuditInfoLink: boolean;
type : string = "Service";
showVidStatus : boolean = true;
auditInfoModalComponentService : AuditInfoModalComponentService;
constructor(private _serviceInfoService: ServiceInfoService, private _iframeService : IframeService,
private _auditInfoModalComponentService : AuditInfoModalComponentService,
+ private _featureFlagsService: FeatureFlagsService,
private store: NgRedux<AppState>) {
this.auditInfoModalComponentService = this._auditInfoModalComponentService;
AuditInfoModalComponent.openModal.subscribe((jobData: ServiceInfoModel) => {
this.isALaCarteFlagOn = this.store.getState().global.flags['FLAG_A_LA_CARTE_AUDIT_INFO'];
+ this.showMoreAuditInfoLink = _featureFlagsService.getFlagState(Features.FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO);
this.initializeProperties();
this.showVidStatus = true;
if (jobData) {
this.openAuditInfoModal(jobData);
_iframeService.addClassOpenModal(this.parentElementClassName);
this.serviceModelName = jobData.serviceModelName ? jobData.serviceModelName : '';
+ this.serviceModelId = jobData.serviceModelId;
+ this.jobId = jobData.jobId;
this.auditInfoModal.show();
} else {
_iframeService.removeClassCloseModal(this.parentElementClassName);
AuditInfoModalComponent.openInstanceAuditInfoModal.subscribe(({instanceId , type , model, instance}) => {
this.showVidStatus = false;
+ this.showMoreAuditInfoLink = false;
this.initializeProperties();
this.setModalTitles(type);
this.serviceModelName = AuditInfoModalComponentService.getInstanceModelName(model);
onNavigate(){
window.open("http://ecompguide.web.att.com:8000/#ecomp_ug/c_ecomp_ops_vid.htmll#r_ecomp_ops_vid_bbglossary", "_blank");
}
+
+ readOnlyRetryUrl = (): string =>
+ `../../serviceModels.htm?more#/servicePlanning/RETRY?serviceModelId=${this.serviceModelId}&jobId=${this.jobId}`
}
--- /dev/null
+<div>
+ <button class="custom-button sdc-button__{{ type }} btn-{{ size }} {{ iconPositionClass }}"
+ [disabled]="disabled || show_spinner"
+ [attr.data-tests-id]="testId">
+ <custom-icon
+ *ngIf="icon_name"
+ [name]="icon_name"
+ [mode]="icon_mode"
+ [size]="'medium'"
+ >
+ </custom-icon>
+ {{text}}
+ </button>
+ <custom-icon *ngIf="show_spinner" name="spinner" [size]="'medium'" class="sdc-button__spinner"
+ [ngClass]="{left: spinner_position === placement.right}"></custom-icon>
+</div>
--- /dev/null
+.custom-button {
+ order: 1;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: row;
+ outline: none;
+ border-radius: 2px;
+ padding: 0 12px;
+ height: 36px;
+ line-height: 36px;
+ width: 120px;
+ min-width: 90px;
+ cursor: pointer;
+ text-align: center;
+ text-transform: uppercase;
+ font-family: OpenSans-Regular, Arial, sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ /*** Sizes ***/
+ /*** Sizes ***/
+ /*** Buttons with icons ***/
+}
+
+.custom-button:disabled {
+ cursor: default;
+}
+
+.custom-button.sdc-button__primary {
+ border: 1px solid transparent;
+ background-color: #009fdb;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__primary:not(:disabled):hover, .custom-button.sdc-button__primary:not(:disabled):active {
+ background-color: #1eb9f3;
+}
+
+.custom-button.sdc-button__primary:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #1eb9f3;
+ box-shadow: 0px 0px 0px 1px #1eb9f3;
+}
+
+.custom-button.sdc-button__primary:disabled {
+ background: #9dd9ef;
+}
+
+.custom-button.sdc-button__secondary {
+ border: 1px solid #009fdb;
+ background-color: transparent;
+ color: #009fdb;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):hover, .custom-button.sdc-button__secondary:not(:disabled):active {
+ background-color: #1eb9f3;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):focus:not(:active) {
+ color: #1eb9f3;
+ box-shadow: inset 0px 0px 0px 0px #0568ae, 0px 0px 0px 1px #009fdb;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):focus:not(:active):hover {
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__secondary:disabled {
+ color: #9dd9ef;
+ border-color: #9dd9ef;
+}
+
+.custom-button.sdc-button__link {
+ background-color: transparent;
+ color: #009fdb;
+ fill: #009fdb;
+ border: none;
+}
+
+.custom-button.sdc-button__link:not(:disabled):hover, .custom-button.sdc-button__link:not(:disabled):active {
+ color: #1eb9f3;
+}
+
+.custom-button.sdc-button__link:not(:disabled):focus:not(:active) {
+ border: 1px solid #0568ae;
+ color: #1eb9f3;
+}
+
+.custom-button.sdc-button__link:disabled {
+ color: #9dd9ef;
+}
+
+.custom-button.sdc-button__success {
+ border: 1px solid transparent;
+ background-color: #4ca90c;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__success:not(:disabled):hover, .custom-button.sdc-button__success:not(:disabled):active {
+ background-color: #57c00e;
+}
+
+.custom-button.sdc-button__success:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #57c00e;
+ box-shadow: 0px 0px 0px 1px #57c00e;
+}
+
+.custom-button.sdc-button__success:disabled {
+ background: #a5d485;
+}
+
+.custom-button.sdc-button__error, .custom-button.sdc-button__alert {
+ border: 1px solid transparent;
+ background-color: #cf2a2a;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__error:not(:disabled):hover, .custom-button.sdc-button__error:not(:disabled):active, .custom-button.sdc-button__alert:not(:disabled):hover, .custom-button.sdc-button__alert:not(:disabled):active {
+ background-color: #ed4141;
+}
+
+.custom-button.sdc-button__error:not(:disabled):focus:not(:active), .custom-button.sdc-button__alert:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #ed4141;
+ box-shadow: 0px 0px 0px 1px #ed4141;
+}
+
+.custom-button.sdc-button__error:disabled, .custom-button.sdc-button__alert:disabled {
+ background: #f4adad;
+}
+
+.custom-button.sdc-button__warning {
+ border: 1px solid transparent;
+ background-color: #ffb81c;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__warning:not(:disabled):hover, .custom-button.sdc-button__warning:not(:disabled):active {
+ background-color: #f6c632;
+}
+
+.custom-button.sdc-button__warning:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #f6c632;
+ box-shadow: 0px 0px 0px 1px #f6c632;
+}
+
+.custom-button.sdc-button__warning:disabled {
+ background: #ffdb8d;
+}
+
+.custom-button.sdc-button__info {
+ border: 1px solid transparent;
+ background-color: #009fdb;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__info:not(:disabled):hover, .custom-button.sdc-button__info:not(:disabled):active {
+ background-color: #1eb9f3;
+}
+
+.custom-button.sdc-button__info:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #1eb9f3;
+ box-shadow: 0px 0px 0px 1px #1eb9f3;
+}
+
+.custom-button.sdc-button__info:disabled {
+ background: #9dd9ef;
+}
+
+.custom-button.sdc-button__file-opener input[type=file] {
+ height: 36px;
+ opacity: 0;
+ position: absolute;
+ cursor: pointer;
+}
+
+.custom-button.btn-xx-large {
+ width: 350px;
+}
+
+.custom-button.btn-xx-large input[type=file] {
+ width: 350px;
+}
+
+.custom-button.btn-x-large {
+ width: 250px;
+}
+
+.custom-button.btn-x-large input[type=file] {
+ width: 250px;
+}
+
+.custom-button.btn-large {
+ width: 180px;
+}
+
+.custom-button.btn-large input[type=file] {
+ width: 180px;
+}
+
+.custom-button.btn-medium {
+ width: 140px;
+}
+
+.custom-button.btn-medium input[type=file] {
+ width: 140px;
+}
+
+.custom-button.btn-small {
+ width: 110px;
+}
+
+.custom-button.btn-small input[type=file] {
+ width: 110px;
+}
+
+.custom-button.btn-x-small {
+ width: 90px;
+}
+
+.custom-button.btn-x-small input[type=file] {
+ width: 90px;
+}
+
+.custom-button.btn-default {
+ width: auto;
+}
+
+.custom-button.btn-default input[type=file] {
+ width: auto;
+}
+
+.custom-button.sdc-icon-right {
+ flex-direction: row-reverse;
+}
+
+.custom-button.sdc-icon-right .svg-icon {
+ margin-left: 15px;
+}
+
+.custom-button.sdc-icon-left {
+ flex-direction: row;
+}
+
+.custom-button.sdc-icon-left .svg-icon {
+ margin-right: 15px;
+}
+
+.custom-button svg {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.sdc-button__wrapper {
+ display: inline-flex;
+}
+
+.sdc-button__spinner {
+ padding-top: 6px;
+ margin: 0 2px;
+}
+
+.sdc-button__spinner.left {
+ order: 2;
+}
--- /dev/null
+import {Component, HostBinding, Input, OnInit} from "@angular/core";
+import {IButtonComponent} from "../customModal/models/modal-button.model";
+import {ButtonType} from "../customModal/models/button.type";
+import {Mode} from "./models/mode.model";
+import {Placement} from "../customModal/models/modal.placement";
+
+
+@Component({
+ selector: "sdc-button",
+ templateUrl: './custom-button.component.html',
+ styleUrls: ['./custom-button.component.scss']
+
+})
+
+export class CustomButtonComponent implements OnInit, IButtonComponent {
+ @Input() public text: string;
+ @Input() public disabled: boolean;
+ @Input() public type: ButtonType;
+ @Input() public icon_mode: Mode;
+ @Input() public size: string;
+ @Input() public preventDoubleClick: boolean;
+ @Input() public icon_name: string;
+ @Input() public icon_position: string;
+ @Input() public show_spinner: boolean;
+ @Input() public spinner_position: Placement;
+ @Input() public testId: string;
+
+ public placement = Placement;
+ private lastClick: Date;
+ public iconPositionClass: string;
+
+ @HostBinding('class.sdc-button__wrapper') true;
+
+ constructor() {
+ this.type = ButtonType.primary;
+ this.size = "default";
+ this.disabled = false;
+ }
+
+ public ngOnInit(): void {
+ this.iconPositionClass = this.icon_position ? 'sdc-icon-' + this.icon_position : '';
+ }
+
+ public onClick = (e): void => {
+ const now: Date = new Date();
+ if (this.preventDoubleClick && this.lastClick && (now.getTime() - this.lastClick.getTime()) <= 500) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ this.lastClick = now;
+ }
+
+ public disableButton = () => {
+ if (!this.disabled) {
+ this.disabled = true;
+ }
+ }
+
+ public enableButton = () => {
+ if (this.disabled) {
+ this.disabled = false;
+ }
+ }
+
+}
--- /dev/null
+export enum Mode {
+ primary = 'primary',
+ primary2 = 'primary2',
+ secondary = 'secondary',
+ success = 'success',
+ error = 'error',
+ warning = 'warning',
+ info = 'info',
+ white = 'white'
+}
--- /dev/null
+<div [ngClass]="classes" [attr.disabled]="disabled || undefined" [innerHtml]="svgIconContentSafeHtml"
+ [attr.data-tests-id]="testId"></div>
--- /dev/null
+@import 'node_modules/onap-ui-common/lib/scss/variables.scss';
+
+:host {
+ display: inline-flex;
+}
+
+@mixin color-icon($primary-color) {
+ color: $primary-color;
+ fill: $primary-color;
+}
+
+@mixin color-icon-hover($secondary-color) {
+ &.clickable {
+ cursor: pointer;
+ &:not([disabled]):hover, &:active, &:focus {
+ @include color-icon($secondary-color);
+ }
+ }
+}
+
+@mixin color-icon-label($primary-color) {
+ @include color-icon($primary-color);
+
+ .custom-icon {
+ @include color-icon($primary-color);
+ }
+}
+
+@mixin color-icon-label-hover($secondary-color) {
+ &.clickable {
+ &:not([disabled]):hover, &:active, &:focus {
+ @include color-icon-label($secondary-color);
+ }
+ }
+}
+
+/deep/ .custom-icon {
+ display: inline-flex;
+ width: 24px;
+ height: 24px;
+ box-sizing: content-box;
+
+ & > svg {
+ width: 100%;
+ height: 100%;
+ }
+
+ &[disabled] {
+ opacity: 0.7;
+ }
+
+ &.mode-primary {
+ @include color-icon($blue);
+ @include color-icon-hover($light-blue);
+ }
+
+ &.mode-primary2 {
+ @include color-icon($dark-gray);
+ @include color-icon-hover($light-blue);
+ }
+
+ &.mode-secondary {
+ @include color-icon($gray);
+ @include color-icon-hover($dark-gray);
+ }
+
+ &.mode-success {
+ @include color-icon($green);
+ }
+
+ &.mode-error {
+ @include color-icon($red);
+ }
+
+ &.mode-warning {
+ @include color-icon($yellow);
+ }
+
+ &.mode-info {
+ @include color-icon($text-black);
+ @include color-icon-hover($dark-blue);
+ }
+
+ &.mode-white {
+ @include color-icon($white);
+ @include color-icon-hover($light-gray);
+ }
+
+ &.size-x_small {
+ width: 8px;
+ height: 8px;
+ }
+
+ &.size-small {
+ width: 12px;
+ height: 12px;
+ }
+
+ &.size-medium {
+ width: 16px;
+ height: 16px;
+ }
+
+ &.size-large {
+ width: 24px;
+ height: 24px;
+ }
+
+ &.size-x_large {
+ width: 36px;
+ height: 36px;
+ }
+
+ &.size-x_x_large {
+ width: 48px;
+ height: 48px;
+ }
+
+ &.bg-type-circle {
+ border-radius: 50%;
+ padding: 6px;
+ }
+
+ &.bg-type-rectangle {
+ padding: 6px;
+ }
+
+ &.bg-color-purple {
+ background-color: $purple;
+ }
+
+ &.bg-color-light-blue {
+ background-color: $light-blue;
+ }
+
+ &.bg-color-green {
+ background-color: $green;
+ }
+
+ &.bg-color-red {
+ background-color: $red;
+ }
+
+ &.bg-color-yellow {
+ background-color: $yellow;
+ }
+
+ &.bg-color-blue {
+ background-color: $blue;
+ }
+
+ &.bg-color-lightBlue {
+ background-color: $light-blue;
+ }
+
+ &.bg-color-darkBlue {
+ background-color: $dark-blue;
+ }
+
+ &.bg-color-darkBlue2 {
+ background-color: $dark-blue2;
+ }
+
+ &.bg-color-disabledBlue {
+ background-color: $disabled-blue;
+ }
+
+ &.bg-color-gray {
+ background-color: $gray;
+ }
+
+ &.bg-color-white {
+ background-color: $white;
+ }
+
+ &.bg-color-transparent {
+ background-color:transparent;
+ }
+ &.bg-color-silver {
+ background-color: $light-silver;
+ }
+}
+
+.custom-icon-wrapper {
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+
+ &.custom-icon-label {
+ }
+
+ &.custom-icon {
+ }
+
+ &[disabled] {
+ opacity: 0.7;
+ }
+
+ &.label-placement-bottom {
+ flex-direction: column;
+ .custom-icon-label {
+ margin-top: 0.25em;
+ }
+ }
+
+ &.label-placement-right {
+ .custom-icon-label {
+ margin-left: 0.25em;
+ }
+ }
+
+ &.label-placement-top {
+ flex-direction: column-reverse;
+ .custom-icon-label {
+ margin-bottom: 0.25em;
+ }
+ }
+
+ &.label-placement-left {
+ flex-direction: row-reverse;
+ .custom-icon-label {
+ margin-right: 0.25em;
+ }
+ }
+
+ &.mode-primary {
+ @include color-icon-label($blue);
+ @include color-icon-label-hover($light-blue);
+ }
+
+ &.mode-secondary {
+ @include color-icon-label($gray);
+ @include color-icon-label-hover($light-blue);
+ }
+
+ &.mode-success {
+ @include color-icon-label($green);
+ }
+
+ &.mode-error {
+ @include color-icon-label($red);
+ }
+
+ &.mode-warning {
+ @include color-icon-label($yellow);
+ }
+
+ &.mode-info {
+ @include color-icon-label($text-black);
+ @include color-icon-label-hover($light-blue);
+ }
+
+ &.size-x_small {
+ font-size: 8px;
+ line-height: 10px;
+
+ .custom-icon {
+ @extend .custom-icon.size-x_small;
+ }
+ }
+
+ &.size-small {
+ font-size: 12px;
+ line-height: 14px;
+
+ .custom-icon {
+ @extend .custom-icon.size-small;
+ }
+ }
+
+ &.size-medium {
+ font-size: 16px;
+ line-height: 20px;
+
+ .custom-icon {
+ @extend .custom-icon.size-medium;
+ }
+ }
+
+ &.size-large {
+ font-size: 24px;
+ line-height: 28px;
+
+ .custom-icon {
+ @extend .custom-icon.size-large;
+ }
+ }
+
+ &.size-x_large {
+ font-size: 34px;
+ line-height: 40px;
+
+ .custom-icon {
+ @extend .custom-icon.size-x_large;
+ }
+ }
+}
--- /dev/null
+import {Component, Input, OnChanges, SimpleChanges} from "@angular/core";
+import {Mode} from "../customButton/models/mode.model";
+import {Size} from "./models/icon-size.model";
+import {BackgroundShape} from "./models/background-shape.model";
+import {BackgroundColor} from "./models/background-color.model";
+import {DomSanitizer, SafeHtml} from "@angular/platform-browser";
+import {iconsMap} from 'onap-ui-common';
+
+@Component({
+ selector: 'custom-icon',
+ templateUrl: './custom-icon.component.html',
+ styleUrls: ['./custom-icon.component.scss'],
+})
+export class SvgIconComponent implements OnChanges {
+
+ @Input() public name: string;
+ @Input() public type: string;
+ @Input() public mode: Mode;
+ @Input() public size: Size;
+ @Input() public backgroundShape: BackgroundShape;
+ @Input() public backgroundColor: BackgroundColor;
+ @Input() public disabled: boolean;
+ @Input() public clickable: boolean;
+ @Input() public className: any;
+ @Input() public testId: string;
+
+ public svgIconContent: string;
+ public svgIconContentSafeHtml: SafeHtml;
+ public svgIconCustomClassName: string;
+ public classes: string;
+
+ constructor(protected domSanitizer: DomSanitizer) {
+ this.size = Size.medium;
+ this.disabled = false;
+ this.type = this.type || "common";
+ }
+
+ static Icons(): { [key: string]: string } {
+ return iconsMap;
+ }
+
+ public ngOnChanges(changes: SimpleChanges) {
+ this.updateSvgIconByName();
+ this.buildClasses();
+ }
+
+ protected updateSvgIconByName() {
+ this.svgIconContent = iconsMap[this.type][this.name] || null;
+ if (this.svgIconContent) {
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.svgIconContent);
+ this.svgIconCustomClassName = '__' + this.name.replace(/\s+/g, '_');
+ } else {
+ this.svgIconContentSafeHtml = null;
+ this.svgIconCustomClassName = 'missing';
+ }
+ }
+
+ private buildClasses = (): void => {
+ const _classes = ['svg-icon'];
+ if (this.mode) {
+ _classes.push('mode-' + this.mode);
+ }
+ if (this.size) {
+ _classes.push('size-' + this.size);
+ }
+ if (this.clickable) {
+ !this.disabled && _classes.push('clickable');
+ }
+ if (this.svgIconCustomClassName) {
+ _classes.push(this.svgIconCustomClassName);
+ }
+ if (this.className) {
+ _classes.push(this.className);
+ }
+ if (this.backgroundShape) {
+ _classes.push('bg-type-' + this.backgroundShape);
+ }
+ if (this.backgroundShape && this.backgroundColor) {
+ _classes.push('bg-color-' + this.backgroundColor);
+ } else if (this.backgroundShape && !this.backgroundColor) {
+ _classes.push('bg-color-primary');
+ }
+ this.classes = _classes.join(" ");
+ }
+}
--- /dev/null
+export enum BackgroundColor {
+ gray = 'gray',
+ purple = 'purple',
+ blue = 'blue',
+ lightBlue = 'light-blue',
+ darkBlue = 'dark-blue',
+ darkBlue2 = 'dark-blue2',
+ disabledBlue = 'disabled-blue',
+ white = 'white',
+ transparent = 'transparent',
+ green = 'green',
+ red = 'red',
+ yellow = 'yellow',
+ silver ='silver'
+}
--- /dev/null
+export enum BackgroundShape {
+ circle = 'circle',
+ rectangle = 'rectangle'
+}
--- /dev/null
+export enum Size {
+ x_large = 'x_large',
+ large = 'large',
+ medium = 'medium',
+ small = 'small',
+ x_small = 'x_small'
+}
--- /dev/null
+<div>
+ <div class="custom-loader-wrapper" *ngIf="!global" [attr.data-tests-id]="testId">
+ <div class="custom-loader-background" *ngIf="active"
+ [style.top]="offset.top" [style.left]="offset.left" [style.width]="offset.width"
+ [style.height]="offset.height">
+ <div class="custom-loader {{ size }}" *ngIf="active"></div>
+ </div>
+ <ng-content></ng-content>
+ </div>
+ <div *ngIf="global && active" [attr.data-tests-id]="testId">
+ <div class="custom-loader-global-wrapper custom-loader-background">
+ <div class="custom-loader {{ size }}"></div>
+ </div>
+ </div>
+</div>
--- /dev/null
+.custom-loader-background {
+ background-color: #000000;
+ position: absolute;
+ z-index: 9999;
+ opacity: 0.5;
+ display: flex;
+ justify-content: center;
+ align-items: center; }
+
+.sdc-loader-wrapper-absolute {
+ position: absolute;
+ top: 0; }
+
+.custom-loader {
+ z-index: 10002; }
+
+.custom-loader-global-wrapper {
+ position: fixed;
+ width: 100%;
+ height: 100%; }
+
+.loader-fixed {
+ display: block;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%; }
+@keyframes fadein {
+ from {
+ opacity: 0; }
+ to {
+ opacity: 0.8; } }
+
+/* Firefox < 16 */
+@-moz-keyframes fadein {
+ from {
+ opacity: 0; }
+ to {
+ opacity: 0.8; } }
+
+/* Safari, Chrome and Opera > 12.1 */
+@-webkit-keyframes fadein {
+ from {
+ opacity: 0; }
+ to {
+ opacity: 0.8; } }
+
+/* Internet Explorer */
+@-ms-keyframes fadein {
+ from {
+ opacity: 0; }
+ to {
+ opacity: 0.8; } }
+
+/* Opera < 12.1 */
+@-o-keyframes fadein {
+ from {
+ opacity: 0; }
+ to {
+ opacity: 0.8; } }
+
+@keyframes fadeout {
+ from {
+ opacity: 0.8; }
+ to {
+ opacity: 0; } }
+
+/* Firefox < 16 */
+@-moz-keyframes fadeout {
+ from {
+ opacity: 0.8; }
+ to {
+ opacity: 0; } }
+
+/* Safari, Chrome and Opera > 12.1 */
+@-webkit-keyframes fadeout {
+ from {
+ opacity: 0.8; }
+ to {
+ opacity: 0; } }
+
+/* Internet Explorer */
+@-ms-keyframes fadeout {
+ from {
+ opacity: 0.8; }
+ to {
+ opacity: 0; } }
+
+/* Opera < 12.1 */
+@-o-keyframes fadeout {
+ from {
+ opacity: 0.8; }
+ to {
+ opacity: 0; } }
+
+.custom-loader {
+ height: 63px;
+ width: 63px;
+ position: absolute; }
+
+.custom-loader.small {
+ transform: scale(0.26); }
+
+.custom-loader.medium {
+ transform: scale(0.5); }
+
+.custom-loader.large {
+ transform: scale(1); }
+
+.custom-loader::before {
+ background-color: #eaeaea;
+ border-radius: 50%;
+ box-shadow: 21px 21px 0px 0px #eaeaea, 0px 42px 0px 0px #eaeaea, -21px 21px 0px 0px #eaeaea;
+ content: '';
+ display: block;
+ height: 21px;
+ width: 21px;
+ position: absolute;
+ left: 50%;
+ margin-left: -10.5px; }
+
+.custom-loader::after {
+ border-radius: 50%;
+ content: '';
+ display: block;
+ position: absolute;
+ height: 21px;
+ width: 21px;
+ animation: dot-move-2 4.5s infinite ease-in; }
+
+@keyframes dot-move {
+ 0% {
+ background-color: #1eb9f3;
+ left: 21px;
+ top: 0; }
+ 25% {
+ background-color: #ffb81c;
+ left: 42px;
+ top: 21px; }
+ 50% {
+ background-color: #caa2dd;
+ left: 21px;
+ top: 42px; }
+ 75% {
+ background-color: #f6c632;
+ left: 0;
+ top: 21px; }
+ 100% {
+ background-color: #1eb9f3;
+ left: 21px;
+ top: 0; } }
+
+@keyframes dot-move-2 {
+ 0% {
+ background-color: #1eb9f3;
+ left: 21px;
+ top: 0; }
+ 6.25% {
+ background-color: #1eb9f3;
+ left: 42px;
+ top: 21px; }
+ 12.5% {
+ background-color: #1eb9f3;
+ left: 21px;
+ top: 42px; }
+ 18.75% {
+ background-color: #1eb9f3;
+ left: 0;
+ top: 21px; }
+ 25% {
+ background-color: #ffb81c;
+ left: 21px;
+ top: 0; }
+ 31.25% {
+ background-color: #ffb81c;
+ left: 42px;
+ top: 21px; }
+ 37.5% {
+ background-color: #ffb81c;
+ left: 21px;
+ top: 42px; }
+ 43.75% {
+ background-color: #ffb81c;
+ left: 0;
+ top: 21px; }
+ 50% {
+ background-color: #caa2dd;
+ left: 21px;
+ top: 0; }
+ 56.25% {
+ background-color: #caa2dd;
+ left: 42px;
+ top: 21px; }
+ 62.5% {
+ background-color: #caa2dd;
+ left: 21px;
+ top: 42px; }
+ 68.75% {
+ background-color: #caa2dd;
+ left: 0;
+ top: 21px; }
+ 75% {
+ background-color: #f6c632;
+ left: 21px;
+ top: 0; }
+ 81.25% {
+ background-color: #f6c632;
+ left: 42px;
+ top: 21px; }
+ 87.5% {
+ background-color: #f6c632;
+ left: 21px;
+ top: 42px; }
+ 93.75% {
+ background-color: #f6c632;
+ left: 0;
+ top: 21px; }
+ 100% {
+ background-color: #1eb9f3;
+ left: 21px;
+ top: 0; } }
--- /dev/null
+import {Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewContainerRef} from "@angular/core";
+import {LoaderSize} from "./models/loader-size.model";
+import {LoaderService} from "./custom-loader.service";
+
+@Component({
+ selector: "custom-loader",
+ templateUrl: './custom-loader.component.html',
+ styleUrls: ['./custom-loader.component.scss']
+
+})
+
+export class LoaderComponent implements OnInit, OnDestroy {
+ @Input() active: number;
+ @Input() size?: LoaderSize;
+ @Input() global?: boolean;
+ @Input() name?: string;
+ @Input() testId: string;
+ @Input() relative: boolean;
+ @Output() activeChange: EventEmitter<number> = new EventEmitter<number>();
+ private offset : {
+ top: string;
+ left: string;
+ width: string;
+ height: string;
+ };
+
+ constructor(private loaderService: LoaderService, private viewContainerRef: ViewContainerRef) {
+ this.active = 0;
+ this.size = LoaderSize.large;
+ this.global = false;
+ }
+
+ public ngOnInit(): void {
+ if (this.name !== undefined) {
+ this.loaderService.register(this.name, this);
+ }
+ this.setLoaderPlace();
+ }
+
+ public ngOnDestroy(): void {
+ if (this.name !== undefined) {
+ this.loaderService.unregister(this.name);
+ }
+ }
+
+ public activate() {
+ this.active++;
+ this.activeChange.emit(this.active);
+ }
+
+ public deactivate() {
+ if (this.active > 0) {
+ this.active--;
+ this.activeChange.emit(this.active);
+ }
+ }
+ public setLoaderPlace = () => {
+ if (this.relative === true) {
+ let parentElement = this.viewContainerRef.element.nativeElement.parentElement;
+ this.offset = {
+ left: (parentElement.offsetLeft !== undefined) ? parentElement.offsetLeft + "px" : undefined,
+ top: (parentElement.offsetTop !== undefined) ? parentElement.offsetTop + "px" : undefined,
+ width: (parentElement.offsetWidth !== undefined) ? parentElement.offsetWidth + "px" : undefined,
+ height: (parentElement.offsetHeight !== undefined) ? parentElement.offsetHeight + "px" : undefined
+ };
+ } else {
+ this.offset = {
+ left: '0px',
+ top: '0px',
+ width: '100%',
+ height: '100%'
+ }
+ }
+ }
+
+}
--- /dev/null
+import {Injectable} from "@angular/core";
+import {LoaderComponent} from "./custom-loader.component";
+
+@Injectable()
+export class LoaderService {
+
+ private mainLoaderName = 'general';
+ public registeredLoaders = {};
+
+ register(name: string, loader: LoaderComponent) {
+ if (!this.registeredLoaders[name]) {
+ this.registeredLoaders[name] = loader;
+ }
+ }
+
+ unregister(name: string) {
+ if (this.registeredLoaders[name]) {
+ delete this.registeredLoaders[name];
+ }
+ }
+
+ activate(name: string = this.mainLoaderName) {
+ if (this.registeredLoaders[name]) {
+ this.registeredLoaders[name].activate();
+ }
+ }
+
+ deactivate(name: string = this.mainLoaderName) {
+ if (this.registeredLoaders[name]) {
+ this.registeredLoaders[name].deactivate();
+ }
+ }
+
+}
--- /dev/null
+export enum LoaderSize {
+ large = 'large',
+ medium = 'medium',
+ small = 'small',
+}
--- /dev/null
+<div>
+ <button class="custom-button sdc-button__{{ type }} btn-{{ size }} {{ iconPositionClass }}"
+ [disabled]="disabled || show_spinner"
+ [attr.data-tests-id]="testId">
+ <custom-icon
+ *ngIf="icon_name"
+ [name]="icon_name"
+ [mode]="icon_mode"
+ [size]="'medium'"
+ >
+ </custom-icon>
+ {{text}}
+ </button>
+ <custom-icon *ngIf="show_spinner" name="spinner" [size]="'medium'" class="sdc-button__spinner"
+ [ngClass]="{left: spinner_position === placement.right}"></custom-icon>
+</div>
--- /dev/null
+.custom-button {
+ order: 1;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: row;
+ outline: none;
+ border-radius: 2px;
+ padding: 0 12px;
+ height: 36px;
+ line-height: 36px;
+ width: 120px;
+ min-width: 90px;
+ cursor: pointer;
+ text-align: center;
+ text-transform: uppercase;
+ font-family: OpenSans-Regular, Arial, sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ /*** Sizes ***/
+ /*** Sizes ***/
+ /*** Buttons with icons ***/
+}
+
+.custom-button:disabled {
+ cursor: default;
+}
+
+.custom-button.sdc-button__primary {
+ border: 1px solid transparent;
+ background-color: #009fdb;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__primary:not(:disabled):hover, .custom-button.sdc-button__primary:not(:disabled):active {
+ background-color: #1eb9f3;
+}
+
+.custom-button.sdc-button__primary:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #1eb9f3;
+ box-shadow: 0px 0px 0px 1px #1eb9f3;
+}
+
+.custom-button.sdc-button__primary:disabled {
+ background: #9dd9ef;
+}
+
+.custom-button.sdc-button__secondary {
+ border: 1px solid #009fdb;
+ background-color: transparent;
+ color: #009fdb;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):hover, .custom-button.sdc-button__secondary:not(:disabled):active {
+ background-color: #1eb9f3;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):focus:not(:active) {
+ color: #1eb9f3;
+ box-shadow: inset 0px 0px 0px 0px #0568ae, 0px 0px 0px 1px #009fdb;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):focus:not(:active):hover {
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__secondary:disabled {
+ color: #9dd9ef;
+ border-color: #9dd9ef;
+}
+
+.custom-button.sdc-button__link {
+ background-color: transparent;
+ color: #009fdb;
+ fill: #009fdb;
+ border: none;
+}
+
+.custom-button.sdc-button__link:not(:disabled):hover, .custom-button.sdc-button__link:not(:disabled):active {
+ color: #1eb9f3;
+}
+
+.custom-button.sdc-button__link:not(:disabled):focus:not(:active) {
+ border: 1px solid #0568ae;
+ color: #1eb9f3;
+}
+
+.custom-button.sdc-button__link:disabled {
+ color: #9dd9ef;
+}
+
+.custom-button.sdc-button__success {
+ border: 1px solid transparent;
+ background-color: #4ca90c;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__success:not(:disabled):hover, .custom-button.sdc-button__success:not(:disabled):active {
+ background-color: #57c00e;
+}
+
+.custom-button.sdc-button__success:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #57c00e;
+ box-shadow: 0px 0px 0px 1px #57c00e;
+}
+
+.custom-button.sdc-button__success:disabled {
+ background: #a5d485;
+}
+
+.custom-button.sdc-button__error, .custom-button.sdc-button__alert {
+ border: 1px solid transparent;
+ background-color: #cf2a2a;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__error:not(:disabled):hover, .custom-button.sdc-button__error:not(:disabled):active, .custom-button.sdc-button__alert:not(:disabled):hover, .custom-button.sdc-button__alert:not(:disabled):active {
+ background-color: #ed4141;
+}
+
+.custom-button.sdc-button__error:not(:disabled):focus:not(:active), .custom-button.sdc-button__alert:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #ed4141;
+ box-shadow: 0px 0px 0px 1px #ed4141;
+}
+
+.custom-button.sdc-button__error:disabled, .custom-button.sdc-button__alert:disabled {
+ background: #f4adad;
+}
+
+.custom-button.sdc-button__warning {
+ border: 1px solid transparent;
+ background-color: #ffb81c;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__warning:not(:disabled):hover, .custom-button.sdc-button__warning:not(:disabled):active {
+ background-color: #f6c632;
+}
+
+.custom-button.sdc-button__warning:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #f6c632;
+ box-shadow: 0px 0px 0px 1px #f6c632;
+}
+
+.custom-button.sdc-button__warning:disabled {
+ background: #ffdb8d;
+}
+
+.custom-button.sdc-button__info {
+ border: 1px solid transparent;
+ background-color: #009fdb;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__info:not(:disabled):hover, .custom-button.sdc-button__info:not(:disabled):active {
+ background-color: #1eb9f3;
+}
+
+.custom-button.sdc-button__info:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #1eb9f3;
+ box-shadow: 0px 0px 0px 1px #1eb9f3;
+}
+
+.custom-button.sdc-button__info:disabled {
+ background: #9dd9ef;
+}
+
+.custom-button.sdc-button__file-opener input[type=file] {
+ height: 36px;
+ opacity: 0;
+ position: absolute;
+ cursor: pointer;
+}
+
+.custom-button.btn-xx-large {
+ width: 350px;
+}
+
+.custom-button.btn-xx-large input[type=file] {
+ width: 350px;
+}
+
+.custom-button.btn-x-large {
+ width: 250px;
+}
+
+.custom-button.btn-x-large input[type=file] {
+ width: 250px;
+}
+
+.custom-button.btn-large {
+ width: 180px;
+}
+
+.custom-button.btn-large input[type=file] {
+ width: 180px;
+}
+
+.custom-button.btn-medium {
+ width: 140px;
+}
+
+.custom-button.btn-medium input[type=file] {
+ width: 140px;
+}
+
+.custom-button.btn-small {
+ width: 110px;
+}
+
+.custom-button.btn-small input[type=file] {
+ width: 110px;
+}
+
+.custom-button.btn-x-small {
+ width: 90px;
+}
+
+.custom-button.btn-x-small input[type=file] {
+ width: 90px;
+}
+
+.custom-button.btn-default {
+ width: auto;
+}
+
+.custom-button.btn-default input[type=file] {
+ width: auto;
+}
+
+.custom-button.sdc-icon-right {
+ flex-direction: row-reverse;
+}
+
+.custom-button.sdc-icon-right .svg-icon {
+ margin-left: 15px;
+}
+
+.custom-button.sdc-icon-left {
+ flex-direction: row;
+}
+
+.custom-button.sdc-icon-left .svg-icon {
+ margin-right: 15px;
+}
+
+.custom-button svg {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.sdc-button__wrapper {
+ display: inline-flex;
+}
+
+.sdc-button__spinner {
+ padding-top: 6px;
+ margin: 0 2px;
+}
+
+.sdc-button__spinner.left {
+ order: 2;
+}
--- /dev/null
+import {Component, EventEmitter, HostListener, Input, Output} from "@angular/core";
+import {CustomButtonComponent} from "../../../customButton/custom-button.component";
+
+@Component({
+ selector: "custom-modal-button",
+ templateUrl: './modal-button.component.html',
+ styleUrls: ['./modal-button.component.scss']
+})
+export class CustomModalButtonComponent extends CustomButtonComponent {
+
+ @Input() public id?: string;
+ @Input() public callback: Function;
+ @Input() public closeModal: boolean;
+ @Output() closeModalEvent: EventEmitter<any> = new EventEmitter<any>();
+ @HostListener('click') invokeCallback = (): void => {
+ if (this.callback) {
+ this.callback();
+ }
+ if (this.closeModal) {
+ this.closeModalEvent.emit();
+ }
+ }
+
+ constructor() {
+ super();
+ this.closeModal = false;
+ }
+}
--- /dev/null
+import {Component, ComponentRef, Input} from "@angular/core";
+import {ModalComponent} from "../../modal.component";
+import {CustomButtonComponent} from "../../../customButton/custom-button.component";
+import {RippleAnimationAction} from "../../directives/ripple-click.animation.directive";
+
+
+@Component({
+ selector: "sdc-modal-close-button",
+ template: `
+ <div class="sdc-modal__close-button"
+ customRippleClickAnimation
+ [ngClass]="disabled ? 'disabled' : ''"
+ [rippleOnAction]="!disabled && rippleAnimationAction"
+ [attr.data-tests-id]="testId"
+ (click)="!disabled && closeModal('close')"
+ >
+ <custom-icon name="close" [mode]="disabled? 'secondary' : 'info'" size="small"></custom-icon>
+ </div>
+ `
+})
+export class ModalCloseButtonComponent extends CustomButtonComponent {
+
+ @Input() testId: string;
+ @Input() disabled: boolean;
+ @Input() modalInstanceRef: ComponentRef<ModalComponent>;
+
+ public rippleAnimationAction: RippleAnimationAction = RippleAnimationAction.MOUSE_ENTER;
+
+ constructor() {
+ super();
+ }
+
+ public closeModal = (btnName: string): void => {
+ this.modalInstanceRef.instance.closeModal(btnName);
+ }
+}
--- /dev/null
+import { Directive, Input, HostBinding, HostListener } from "@angular/core";
+
+export enum RippleAnimationAction {
+ CLICK = 0,
+ MOUSE_ENTER = 1
+}
+
+@Directive({
+ selector: `[customRippleClickAnimation]`
+})
+export class CustomRippleClickAnimationDirective {
+ private animated: boolean;
+
+ @Input() rippleClickDisabled: boolean;
+ @Input() rippleOnAction:RippleAnimationAction = RippleAnimationAction.CLICK;
+
+ @HostBinding('class.sdc-ripple-click__animated') animationClass: string;
+
+ @HostListener('click') onClick() {
+ if(this.rippleOnAction === RippleAnimationAction.CLICK){
+ this.animateStart();
+ }
+ }
+
+ @HostListener('mouseenter') onMouseEnter() {
+ //console.log("Mouseenter!", this.rippleOnAction);
+ if(this.rippleOnAction === RippleAnimationAction.MOUSE_ENTER){
+ this.animateStart();
+ }
+ }
+
+ private animateStart():void{
+ if (!this.rippleClickDisabled) {
+ this.animated = true;
+ this.animationClass = 'sdc-ripple-click__animated';
+ }
+ }
+ @HostListener('animationend') onAnimationComplete() {
+ this.animated = false;
+ this.animationClass = '';
+ }
+
+ constructor() {
+ this.rippleClickDisabled = false;
+ this.animated = false;
+ }
+}
--- /dev/null
+<div>
+ <div class="modal-background" [@toggleBackground]="modalVisible" ></div>
+ <div class="sdc-modal {{size}}">
+ <div class="sdc-modal__wrapper sdc-modal-type-{{type}}" [@toggleModal]="modalVisible" (@toggleModal.done)="modalToggled($event)">
+
+ <div class="sdc-modal__header sdc-{{type}}__header">
+ <div class="sdc-modal__icon" *ngIf="type!='custom'" [innerHtml]="svgIconContentSafeHtml"></div>
+
+ <div *ngIf="title" class="title" >
+ {{ title }}
+ <custom-icon
+ *ngIf="titleIcon"
+ [name]="titleIcon.iconName"
+ [mode]="titleIcon.iconMode"
+ [size]="titleIcon.iconSize">
+ </custom-icon>
+ </div>
+ <sdc-modal-close-button #modalCloseButton [testId]="'close' | calculateTestId : testId" [modalInstanceRef]="instanceRef"></sdc-modal-close-button>
+ </div>
+
+ <div class="sdc-modal__content">
+ <div *ngIf="message" [innerHtml]="message"></div>
+ <div #dynamicContentContainer></div>
+ <div class="disabled-modal" *ngIf="isDisabled"></div>
+ </div>
+
+ <div class="sdc-modal__footer">
+ <custom-modal-button *ngFor="let button of buttons"
+ [text]="button.text"
+ [type]="button.type || 'primary'"
+ [disabled]="button.disabled"
+ [size] = "button.size ? button.size : 'default'"
+ [closeModal]="button.closeModal"
+ [spinner_position]="button.spinner_position"
+ [show_spinner]="button.show_spinner"
+ [callback]="button.callback"
+ [testId]="'button-' + button.text | calculateTestId : testId"
+ (closeModalEvent)="closeModal(button.text)"
+ >
+ </custom-modal-button>
+ </div>
+
+ </div>
+ </div>
+</div>
+
--- /dev/null
+import {
+ Component,
+ ComponentRef,
+ EventEmitter,
+ Input,
+ OnInit,
+ Output,
+ Renderer,
+ ViewChild,
+ ViewContainerRef
+} from "@angular/core";
+import {animate, style, transition, trigger} from "@angular/animations";
+import {TitleIconDetails} from "./models/modal.model";
+import {ModalType} from "./models/modal.type";
+import {DomSanitizer, SafeHtml} from "@angular/platform-browser";
+import {ModalCloseButtonComponent} from "./components/modalCloseButton/modal-close-button.component";
+import {CustomModalButtonComponent} from "./components/modalButton/modal-button.component";
+
+@Component({
+ selector: 'sdc-modal',
+ templateUrl: './modal.component.html',
+ animations: [
+ trigger('toggleBackground', [
+ transition('* => 1', [style({ opacity: 0 }), animate('.45s cubic-bezier(0.23, 1, 0.32, 1)')]),
+ transition('1 => *', [animate('.35s cubic-bezier(0.23, 1, 0.32, 1)', style({ opacity: 0 }))])
+ ]),
+ trigger('toggleModal', [
+ transition('* => 1', [style({ opacity: 0, transform: 'translateY(-80px)' }), animate('.45s cubic-bezier(0.23, 1, 0.32, 1)')]),
+ transition('1 => *', [style({ opacity: 1, transform: 'translateY(0px)' }), animate('.35s ease-in-out', style({ opacity: 0, transform: 'translateY(-80px)' }))])
+ ])
+ ]
+})
+
+export class ModalComponent implements OnInit {
+
+ @Input() size: string; 'xl|l|md|sm|xsm';
+ @Input() title: string;
+ @Input() titleIcon: TitleIconDetails;
+ @Input() message: string;
+ @Input() buttons: CustomModalButtonComponent[];
+ @Input() type: ModalType;
+ @Input() testId: string;
+ @Input() isDisabled: boolean;
+ @Input() instanceRef: ComponentRef<ModalComponent>; // the component ref is injected to the component in order to destroy the componet from itself
+
+ @Output() onClose : EventEmitter<string> = new EventEmitter<string>();
+
+ @ViewChild('modalCloseButton', {static: false})
+ set refCloseButton(_modalCloseButton: ModalCloseButtonComponent) {
+ this.modalCloseButton = _modalCloseButton;
+ }
+
+ modalVisible: boolean;
+ // Allows for custom component as body instead of simple message.
+ @ViewChild('dynamicContentContainer', { read: ViewContainerRef, static: true }) dynamicContentContainer: ViewContainerRef;
+ innerModalContent: ComponentRef<any>;
+
+ public calculatedTestId: string;
+ public modalCloseButton: ModalCloseButtonComponent;
+ public svgIconContentSafeHtml: SafeHtml;
+
+
+ private infoSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24">
+ <defs><path fill="#000" id="info-a" d="M11,20 C6,20 2,16 2,11 C2,6 6,2 11,2 C16,2 20,6 20,11 C20,16 16,20 11,20 M11,0 C4.9,0 0,4.9 0,11 C0,17.101 4.9,22 11,22 C17.1,22 22,17.101 22,11 C22,4.9 17.1,0 11,0 M11,10 C10.4,
+ 10 10,10.4 10,11 L10,15 C10,15.601 10.4,16 11,16 C11.6,16 12,15.601 12,15 L12,11 C12,10.4 11.6,10 11,10 M10.2998,6.2998 C10.0998,6.4998 9.9998,6.6998 9.9998,6.9998 C9.9998,7.2998 10.0998,7.4998 10.2998,7.6998 C10.4998,
+ 7.9008 10.6998,7.9998 10.9998,7.9998 C11.2998,7.9998 11.4998,7.9008 11.6998,7.6998 C11.9008,7.4998 11.9998,7.2998 11.9998,6.9998 C11.9998,6.6998 11.9008,6.4998 11.6998,6.2998 C11.2998,5.9008 10.6998,5.9008 10.2998,6.2998"/>
+ </defs><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><use class="sdc-modal__svg-use" xlink:href="#info-a"/></g></svg>`;
+ private warningSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24"><defs><path fill="#000" id="alert-a" d="M20.5815,18.7997 C20.3815,
+ 18.9997 20.0815,19.0997 19.8815,19.0997 L2.8815,19.0997 C2.6815,19.0997 2.5815,19.0997 2.3815,18.9997 C1.8815,18.6997 1.7815,18.0997 1.9815,17.5997 L10.4815,3.4997 C10.5815,3.4007 10.6815,3.1997 10.7815,3.1997 C11.2815,
+ 2.9007 11.8815,3.0997 12.1815,3.4997 L20.6825,17.5997 C20.7815,17.6997 20.7815,17.9007 20.7815,18.0997 C20.8815,18.4007 20.6825,18.5997 20.5815,18.7997 M22.3815,16.5997 L13.9815,2.4007 C13.5815,1.6997 12.8815,1.1997 12.0815,
+ 0.9997 C11.2815,0.7997 10.4815,0.9007 9.7815,1.2997 C9.3815,1.4997 8.9815,1.9007 8.7815,2.2997 L0.3815,16.5997 C-0.4185,17.9997 0.0815,19.9007 1.4815,20.6997 C1.8815,20.9997 2.3815,21.0997 2.8815,21.0997 L19.8815,
+ 21.0997 C20.6825,21.0997 21.4815,20.7997 21.9815,20.1997 C22.5815,19.5997 22.8815,18.9007 22.8815,18.0997 C22.7815,17.5997 22.6825,16.9997 22.3815,16.5997 M11,7 C10.4,7 10,7.4 10,8 L10,12 C10,12.601 10.4,13 11,13 C11.6,13 12,
+ 12.601 12,12 L12,8 C12,7.4 11.6,7 11,7 M10.3,15.3 C10.1,15.499 10,15.699 10,15.999 C10,16.3 10.1,16.499 10.3,16.699 C10.5,16.9 10.7,16.999 11,16.999 C11.3,16.999 11.5,16.9 11.7,16.699 C11.9,16.499 12,16.199 12,15.999 C12,
+ 15.8 11.9,15.499 11.7,15.3 C11.3,14.9 10.7,14.9 10.3,15.3"/></defs><g fill="#ffb81c" fill-rule="evenodd" transform="translate(1 1)"><use class="sdc-modal__svg-use" xlink:href="#alert-a"/></g></svg>`;
+ private errorSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24"><defs><path fill="#000" id="x-a" d="M11,20 C6,20 2,16 2,11 C2,6 6,2 11,
+ 2 C16,2 20,6 20,11 C20,16 16,20 11,20 M11,0 C4.9,0 0,4.9 0,11 C0,17.1 4.9,22 11,22 C17.1,22 22,17.1 22,11 C22,4.9 17.1,0 11,0 M14.2591,7.29935 C13.8591,6.90035 13.2591,6.90035 12.8591,7.29935 L10.5591,9.59935 L8.2591,
+ 7.29935 C7.8591,6.90035 7.2591,6.90035 6.8591,7.29935 C6.4591,7.69935 6.4591,8.29935 6.8591,8.69935 L9.1581,10.99935 L6.8591,13.29935 C6.4591,13.69935 6.4591,14.29935 6.8591,14.69935 C7.0591,14.90035 7.2591,14.99935 7.5591,
+ 14.99935 C7.8591,14.99935 8.0591,14.90035 8.2591,14.69935 L10.5591,12.40035 L12.8591,14.69935 C13.0591,14.90035 13.3591,14.99935 13.5591,14.99935 C13.7591,14.99935 14.0591,14.90035 14.2591,14.69935 C14.6581,14.29935 14.6581,
+ 13.69935 14.2591,13.29935 L11.9591,10.99935 L14.2591,8.69935 C14.6581,8.29935 14.6581,7.69935 14.2591,7.29935"/></defs><g fill="none" fill-rule="evenodd" transform="translate(1 1)">
+ <use class="sdc-modal__svg-use" xlink:href="#x-a"/></g></svg>`;
+ private successSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24" fill="#4ca90c"><path id="success+20-a" d="M20.1825992,10.445793 C20.6735306,
+ 10.445793 21.0008182,10.7730806 21.0008182,11.264012 L21.0008182,12.0004091 C21.0008182,16.9915451 16.9915451,21 12.0004091,21 C7.00927315,21 3,16.9915451 3,12.0004091 C3,7.00927315 7.00927315,3 12.0004091,3 C13.3095595,3 14.536888,
+ 3.3272876 15.6823947,3.81821901 C16.0915042,3.98186281 16.255148,4.47279422 16.0915042,4.88190372 C15.9278604,5.29101323 15.436929,5.45465703 15.0278194,5.29101323 C14.0459566,4.88190372 13.0640938,4.63643802 12.0004091,
+ 4.63643802 C7.90931406,4.63643802 4.63643802,7.90931406 4.63643802,12.0004091 C4.63643802,16.0906859 7.90931406,19.363562 12.0004091,19.363562 C16.0915042,19.363562 19.3643802,16.0906859 19.3643802,12.0004091 L19.3643802,
+ 11.264012 C19.3643802,10.7730806 19.6916678,10.445793 20.1825992,10.445793 Z M21.5737352,4.06343925 C21.9002046,4.39072685 21.9002046,4.88165826 21.5737352,5.20894586 L12.5733261,14.209355 C12.4096823,14.3729988 12.1642166,
+ 14.4548207 12.0005728,14.4548207 C11.836929,14.4548207 11.5914632,14.3729988 11.4278194,14.209355 L8.97316242,11.7546979 C8.64587481,11.4274103 8.64587481,10.9364789 8.97316242,10.6091913 C9.30045002,10.2819037 9.79138143,
+ 10.2819037 10.118669,10.6091913 L12.0005728,12.491095 L20.4282286,4.06343925 C20.7555162,3.73615164 21.2464476,3.73615164 21.5737352,4.06343925 Z"></path></svg>`;
+ private noSvg = ``;
+
+ constructor(private renderer: Renderer,
+ private domSanitizer: DomSanitizer) {
+ this.modalVisible = true;
+ }
+
+ ngOnInit() {
+
+ switch (this.type) {
+ case ModalType.info:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.infoSvg);
+ break;
+ case ModalType.warning:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.warningSvg);
+ break;
+ case ModalType.error:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.errorSvg);
+ break;
+ case ModalType.success:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.successSvg);
+ break;
+ default:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.noSvg);
+ }
+ }
+
+ public modalToggled = (toggleEvent: any) => {
+ if (!toggleEvent.toState) {
+ this.instanceRef.destroy();
+ }
+ }
+
+ public getCloseButton = (): ModalCloseButtonComponent => {
+ return this.modalCloseButton;
+ }
+
+ public getButtonById = (id: string): CustomModalButtonComponent => {
+ // Support ES5
+ // return this.buttons.find((button) => {
+ return this.buttons.filter((button) => {
+ return button.id && button.id === id;
+ })[0];
+ }
+
+ public getButtons = (): CustomModalButtonComponent[] => {
+ return this.buttons;
+ }
+
+ public setButtons = (_buttons: CustomModalButtonComponent[]): void => {
+ this.buttons = _buttons;
+ }
+
+ public getTitle = (): string => {
+ return this.title;
+ }
+
+ public setTitle = (_title: string): void => {
+ this.title = _title;
+ }
+
+ public hoverAnimation(evn: MouseEvent) {
+ this.renderer.setElementClass(evn.target as HTMLElement, 'sdc-ripple-click__animated', true);
+ // evn.taregt.classList.add('sdc-ripple-click__animated');
+ }
+
+ public closeModal = (btnName : string): void => {
+ this.onClose.emit(btnName);
+ this.modalVisible = false;
+ }
+
+ public disabledModal = (isDisabled: boolean): void => {
+ this.isDisabled = isDisabled;
+ this.buttons.forEach((button: CustomModalButtonComponent) => {
+ button.disabled = isDisabled;
+ });
+ this.modalCloseButton.disabled = false;
+ }
+}
--- /dev/null
+export enum ButtonType {
+ primary = 'primary',
+ secondary = 'secondary',
+ success = 'success',
+ error = 'error',
+ warning = 'warning',
+ info = 'info'
+}
--- /dev/null
+import {ButtonType} from "onap-ui-angular/dist/dist/common";
+import {Placement} from "./modal.placement";
+
+export interface IButtonComponent {
+ text: string;
+ disabled?: boolean;
+ type?: ButtonType;
+ testId?: string;
+ preventDoubleClick?: boolean;
+ icon_name?: string;
+ icon_position?: string;
+ show_spinner?: boolean;
+ spinner_position?: Placement;
+ size?: string;
+}
--- /dev/null
+import {ModalType} from "./modal.type";
+import {IButtonComponent} from "./modal-button.model";
+
+export interface IModalConfig {
+ size?: string; // xl|l|md|sm|xsm
+ title?: string;
+ titleIcon?: TitleIconDetails;
+ message?: string;
+ buttons?: IModalButtonComponent[];
+ testId?: string;
+ type?: ModalType;
+}
+
+export interface IModalButtonComponent extends IButtonComponent {
+ id?: string;
+ callback?: () => void;
+ closeModal?: boolean;
+}
+
+export interface TitleIconDetails {
+ iconName?: string;
+ iconMode?: string;
+ iconSize?: string;
+}
+
+
--- /dev/null
+export enum Placement {
+ left = 'left',
+ right = 'right',
+ top = 'top',
+ bottom = 'bottom'
+}
--- /dev/null
+export enum ModalSize {
+ xlarge = "xl",
+ large = "l",
+ medium = "md",
+ small = "sm",
+ xsmall = "xsm"
+}
--- /dev/null
+export enum ModalType {
+ info = 'info',
+ warning = 'warning',
+ error = 'error',
+ success = 'success',
+ action = 'action',
+ custom = 'custom'
+}
+
+
--- /dev/null
+import {
+ ApplicationRef,
+ ComponentFactoryResolver,
+ ComponentRef,
+ EmbeddedViewRef,
+ Injectable,
+ Injector, Type, ViewContainerRef
+} from "@angular/core";
+
+@Injectable()
+export class CreateDynamicComponentService {
+
+ constructor(private componentFactoryResolver: ComponentFactoryResolver,
+ private applicationRef: ApplicationRef,
+ private injector: Injector) {
+ }
+
+ /**
+ * Gets the root view container to inject the component to.
+ *
+ * @returns {ComponentRef<any>}
+ *
+ * @memberOf InjectionService
+ */
+ private getRootViewContainer(): ComponentRef<any> {
+ const rootComponents = this.applicationRef['components'];
+ if (rootComponents.length) {
+ return rootComponents[0];
+ }
+ throw new Error('View Container not found! ngUpgrade needs to manually set this via setRootViewContainer.');
+ }
+
+ /**
+ * Gets the html element for a component ref.
+ *
+ * @param {ComponentRef<any>} componentRef
+ * @returns {HTMLElement}
+ *
+ * @memberOf InjectionService
+ */
+ private getComponentRootNode(componentRef: ComponentRef<any>): HTMLElement {
+ return (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
+ }
+
+ /**
+ * Gets the root component container html element.
+ *
+ * @returns {HTMLElement}
+ *
+ * @memberOf InjectionService
+ */
+ private getRootViewContainerNode(): HTMLElement {
+ return this.getComponentRootNode(this.getRootViewContainer());
+ }
+
+ /**
+ * Projects the inputs onto the component
+ *
+ * @param {ComponentRef<any>} component
+ * @param {*} options
+ * @returns {ComponentRef<any>}
+ *
+ * @memberOf InjectionService
+ */
+ private projectComponentInputs(component: ComponentRef<any>, options: any): ComponentRef<any> {
+ if (options) {
+ const props = Object.getOwnPropertyNames(options);
+ for (const prop of props) {
+ component.instance[prop] = options[prop];
+ }
+ }
+
+ return component;
+ }
+
+ public createComponentDynamically<T>(componentClass: Type<T>, options: any = {}, location: Element = this.getRootViewContainerNode()): ComponentRef<any> {
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentClass);
+ const componentRef = componentFactory.create(this.injector);
+ const componentRootNode = this.getComponentRootNode(componentRef);
+
+ // project the options passed to the component instance
+ this.projectComponentInputs(componentRef, options);
+ this.applicationRef.attachView(componentRef.hostView);
+
+ componentRef.onDestroy(() => {
+ this.applicationRef.detachView(componentRef.hostView);
+ });
+
+ location.appendChild(componentRootNode);
+ return componentRef;
+ }
+
+ /**
+ * Inserts a component into an existing viewContainer
+ * @param componentType - type of component to create
+ * @param options - Inputs to project on new component
+ * @param vcRef - viewContainerRef in which to insert the newly created component
+ */
+ public insertComponentDynamically<T>(componentType: Type<T>, options: any = {}, vcRef: ViewContainerRef): ComponentRef<any> {
+ const factory = this.componentFactoryResolver.resolveComponentFactory(componentType);
+ const dynamicComponent = factory.create(vcRef.parentInjector);
+ this.projectComponentInputs(dynamicComponent, options);
+ vcRef.insert(dynamicComponent.hostView);
+ return dynamicComponent;
+ }
+
+}
--- /dev/null
+import {ComponentRef, Injectable, Type} from "@angular/core";
+import {CreateDynamicComponentService} from "./create-dynamic-component.service";
+import {ModalType} from "../models/modal.type";
+import {ButtonType} from "../models/button.type";
+import {ModalButtonComponent} from "onap-ui-angular/dist/modals/modal-button.component";
+import {ModalSize} from "../models/modal.size";
+import {IModalConfig} from "../models/modal.model";
+import {ModalComponent} from "../modal.component";
+
+
+@Injectable()
+export class ModalService {
+
+ constructor(private createDynamicComponentService: CreateDynamicComponentService) {
+ }
+
+ private getBaseModal = (type: ModalType | ButtonType, title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ const modalConfig = {
+ size: ModalSize.small,
+ title: title,
+ message: message,
+ testId: testId,
+ buttons: buttons ? buttons : [{text: 'OK', type: type, closeModal: true}],
+ type: type
+ } as IModalConfig;
+ const modalInstance: ComponentRef<ModalComponent> = this.openModal(modalConfig);
+ return modalInstance.instance;
+ };
+
+ /* Shortcut method to open basic modals with title, message, and OK button that simply closes the modal. */
+ public openInfoModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+
+ return this.getBaseModal(ModalType.info, title, message, testId, buttons);
+ };
+
+ public openWarningModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ return this.getBaseModal(ModalType.warning, title, message, testId, buttons);
+ };
+
+ public openErrorModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ return this.getBaseModal(ModalType.error, title, message, testId, buttons);
+ };
+
+ public openSuccessModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ return this.getBaseModal(ModalType.success, title, message, testId, buttons);
+ };
+
+ public openCustomModal = (modalConfig: IModalConfig, dynamicComponentType: Type<any>, dynamicComponentInput?: any) => {
+ const modalInstance: ComponentRef<ModalComponent> = this.openModal(modalConfig);
+ this.createInnnerComponent(modalInstance, dynamicComponentType, dynamicComponentInput);
+ return modalInstance.instance;
+ };
+
+ public createInnnerComponent = (modalInstance: ComponentRef<ModalComponent>, dynamicComponentType: Type<any>, dynamicComponentInput?: any): void => {
+ modalInstance.instance.innerModalContent = this.createDynamicComponentService.insertComponentDynamically(dynamicComponentType, dynamicComponentInput, modalInstance.instance.dynamicContentContainer);
+ };
+
+ public openModal = (customModalData: IModalConfig): ComponentRef<ModalComponent> => {
+ let modalInstance: ComponentRef<ModalComponent> = this.createDynamicComponentService.createComponentDynamically(ModalComponent, customModalData);
+ modalInstance.instance.instanceRef = modalInstance;
+ return modalInstance;
+ }
+
+}
--- /dev/null
+import {AfterViewInit, Component, ViewChild, ViewContainerRef} from "@angular/core";
+import {BehaviorSubject} from "rxjs";
+
+@Component({
+ selector: 'tooltip-template',
+ template: `
+ <div class="custom-tooltip-template-container">
+ <ng-container #templateContainer></ng-container>
+ </div>`
+})
+
+export class TooltipTemplateComponent implements AfterViewInit {
+ @ViewChild('templateContainer', {read: ViewContainerRef, static: true}) public container: ViewContainerRef;
+
+ public viewReady: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
+
+ ngAfterViewInit() : void {
+ this.viewReady.next(true);
+ }
+}
--- /dev/null
+import {Directive, ElementRef, HostListener, Input, OnInit, Renderer, TemplateRef} from "@angular/core";
+import {CreateDynamicComponentService} from "../customModal/services/create-dynamic-component.service";
+import {TooltipTemplateComponent} from "./custom-tooltip.component";
+
+const pixel = 'px';
+const leftStyle = 'left';
+const topStyle = 'top';
+const showSuffix = 'show';
+const rightBottomSuffix = 'right__bottom';
+const centerMiddleSuffix = 'center__middle';
+
+@Directive({
+ selector: '[custom-tooltip]'
+})
+export class TooltipDirective implements OnInit {
+ @Input('tooltip-text') public text;
+ @Input('tooltip-placement') public placement: TooltipPlacement = TooltipPlacement.Top;
+ @Input('tooltip-css-class') public customCssClass: string;
+ @Input('tooltip-template') public template: TemplateRef<any>;
+ @Input('tooltip-arrow-offset') public arrowOffset: number = 10;
+ @Input('tooltip-arrow-placement') public arrowPlacement: ArrowPlacement = ArrowPlacement.LeftTop;
+ @Input('tooltip-offset') public tooltipOffset: number = 3;
+
+ private cssClass: string = 'sdc-tooltip'; // default css class
+ private tooltip: any; // tooltip html element
+ private elemPosition: any;
+ private tooltipTemplateContainer: any;
+
+ private scrollEventHandler = () => {};
+
+ constructor(
+ private elementRef: ElementRef,
+ private service: CreateDynamicComponentService,
+ private renderer: Renderer) {
+
+ this.elementRef.nativeElement.title = "";
+ }
+
+ @HostListener('mouseenter')
+ public onMouseEnter() {
+ this.show();
+ this.activateScrollEvent();
+ }
+
+ @HostListener('mouseleave')
+ public onMouseLeave() {
+ this.hide();
+ this.deactivateScrollEvent();
+ }
+
+ ngOnInit(): void {
+ this.initScrollEvent();
+ }
+
+ private get ScreenWidth() {
+ return document.documentElement.clientWidth;
+ }
+
+ private get ScreenHeight() {
+ return document.documentElement.clientHeight;
+ }
+
+ private create() {
+ this.tooltipTemplateContainer = this.service.createComponentDynamically(TooltipTemplateComponent, document.body);
+
+ /**
+ * Creating a view (injecting our template) from template in our component.
+ */
+ this.tooltip = this.tooltipTemplateContainer.location.nativeElement.querySelector(
+ '.sdc-tooltip-template-container');
+
+ if (this.template) {
+ this.tooltipTemplateContainer.instance.container.createEmbeddedView(this.template);
+ } else if(this.text) {
+ this.tooltip.textContent = this.text;
+ } else {
+ this.tooltip = undefined;
+ }
+
+ this.setCssClass(true);
+ }
+
+ private destroy() {
+ this.tooltipTemplateContainer.destroy();
+ this.tooltip = null;
+ }
+
+ private show() {
+ this.create();
+
+ /**
+ * View is ready (AfterViewInit event in template component)
+ */
+ this.tooltipTemplateContainer.instance.viewReady.subscribe((isReady) => {
+ if (isReady) {
+ this.setPosition();
+ this.toggleShowCssClass(true); // add css class
+ }
+ });
+ }
+
+ private hide() {
+ this.toggleShowCssClass(false); // remove css class
+
+ this.destroy();
+ }
+
+ private toggleShowCssClass(isAdd: boolean) {
+ if (this.tooltip) {
+ this.setCssClass(isAdd, '-' + showSuffix);
+ }
+ }
+
+ /**
+ * Adds placement css class and sets tooltip position in style
+ */
+ private setPosition() {
+ const tooltipPos: IPlacementData = this.getPlacementData();
+
+ const placementSuffix: string = TooltipPlacement[tooltipPos.placement].toLowerCase();
+
+ this.setCssClass(true, '-' + placementSuffix);
+
+ this.setAdditionalCssClass(placementSuffix);
+
+ this.renderer.setElementStyle(this.tooltip, topStyle, tooltipPos.top + pixel);
+ this.renderer.setElementStyle(this.tooltip, leftStyle, tooltipPos.left + pixel);
+ }
+
+ private setAdditionalCssClass(placementSuffix: string) {
+ if (this.arrowPlacement === ArrowPlacement.RightBottom) {
+ this.setCssClass(true, '-' + placementSuffix + '-' + rightBottomSuffix);
+ } else if (this.arrowPlacement === ArrowPlacement.CenterMiddle) {
+ this.setCssClass(true, '-' + placementSuffix + '-' + centerMiddleSuffix);
+ }
+ }
+
+ private setCssClass(isAdd: boolean, suffix: string = '') {
+ this.renderer.setElementClass(this.tooltip, this.cssClass + suffix, isAdd);
+
+ if (this.customCssClass) {
+ this.renderer.setElementClass(this.tooltip, this.customCssClass + suffix, isAdd);
+ }
+ }
+
+ /**
+ * Checks the specified placement (first element in array), if it is not valid - checks other placements
+ * @returns {IPlacementData}
+ */
+ private getPlacementData(): IPlacementData {
+ const placement: TooltipPlacement = this.placement;
+ let tooltipPos: IPlacementData;
+
+ const tooltipPosWithPlacement = this.getPlacement.bind(this, placement);
+
+ // TODO add comments - done
+ switch (placement) {
+ case TooltipPlacement.Left:
+ tooltipPos = tooltipPosWithPlacement(
+ TooltipPlacement.Right,
+ TooltipPlacement.Top,
+ TooltipPlacement.Bottom);
+ break;
+
+ case TooltipPlacement.Right:
+ tooltipPos = tooltipPosWithPlacement(
+ TooltipPlacement.Left,
+ TooltipPlacement.Top,
+ TooltipPlacement.Bottom);
+ break;
+
+ case TooltipPlacement.Top:
+ tooltipPos = tooltipPosWithPlacement(
+ TooltipPlacement.Bottom,
+ TooltipPlacement.Left,
+ TooltipPlacement.Right);
+ break;
+
+ case TooltipPlacement.Bottom:
+ tooltipPos = tooltipPosWithPlacement(
+ TooltipPlacement.Top,
+ TooltipPlacement.Left,
+ TooltipPlacement.Right);
+ break;
+ }
+
+ return tooltipPos;
+ }
+
+ /**
+ * Returns valid tooltip position data
+ * @param {TooltipPlacement} placement
+ * @param {TooltipPlacement} additionalPlacements
+ * @returns {IPlacementData}
+ */
+ private getPlacement(placement: TooltipPlacement,
+ ...additionalPlacements: TooltipPlacement[]
+ ): IPlacementData {
+ const placements: TooltipPlacement[] = [placement, ...additionalPlacements];
+ const filterPlacements = placements
+ .map((pl) => this.getPosition(pl))
+ .filter((item) => this.validatePosition(item));
+ return filterPlacements.length > 0 ? filterPlacements[0] : this.getPosition(placement);
+ }
+
+ /**
+ * Returns input data for getPosition method
+ * @returns {ITooltipPositionParams}
+ */
+ private getPlacementInputParams(): ITooltipPositionParams {
+ this.elemPosition = this.elementRef.nativeElement.getBoundingClientRect();
+
+ return {
+ elemHeight: this.elementRef.nativeElement.offsetHeight,
+ elemLeft: this.elemPosition.left,
+ elemTop: this.elemPosition.top,
+ elemWidth: this.elementRef.nativeElement.offsetWidth,
+ pageYOffset: window.pageYOffset,
+ tooltipHeight: this.tooltip.offsetHeight, // .clientHeight,
+ tooltipOffset: this.tooltipOffset,
+ tooltipWidth: this.tooltip.offsetWidth,
+ arrowOffset: this.arrowOffset
+ };
+ }
+
+ /**
+ * Returns tooltip position data
+ * @param {TooltipPlacement} placement (left, top, right, bottom)
+ * @returns {IPlacementData}
+ */
+ private getPosition(placement: TooltipPlacement): IPlacementData {
+ switch(this.arrowPlacement) {
+ case ArrowPlacement.LeftTop:
+ return this.getLeftTopPosition(placement);
+
+ case ArrowPlacement.RightBottom:
+ return this.getRightBottomPosition(placement);
+ }
+
+ return this.getCenterMiddlePosition(placement);
+ }
+
+ /**
+ * Returns tooltip position data (center / middle arrow)
+ * @param {TooltipPlacement} placement (left, top, right, bottom)
+ * @returns {IPlacementData}
+ */
+ private getCenterMiddlePosition(placement: TooltipPlacement): IPlacementData {
+ let left = 0;
+ let top = 0;
+
+ const inputPos: ITooltipPositionParams = this.getPlacementInputParams();
+ switch (placement) {
+ case TooltipPlacement.Left:
+ left = inputPos.elemLeft - inputPos.tooltipWidth - inputPos.tooltipOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight / 2 - inputPos.tooltipHeight / 2;
+ break;
+
+ case TooltipPlacement.Right:
+ left = inputPos.elemLeft + inputPos.elemWidth + inputPos.tooltipOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight / 2 - inputPos.tooltipHeight / 2;
+ break;
+
+ case TooltipPlacement.Top:
+ left = inputPos.elemLeft + inputPos.elemWidth / 2 - inputPos.tooltipWidth / 2;
+ top = inputPos.elemTop + inputPos.pageYOffset - inputPos.tooltipHeight - inputPos.tooltipOffset;
+ break;
+
+ case TooltipPlacement.Bottom:
+ left = inputPos.elemLeft + inputPos.elemWidth / 2 - inputPos.tooltipWidth / 2;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight + inputPos.tooltipOffset;
+ break;
+ }
+
+ return {
+ height: inputPos.tooltipHeight,
+ left,
+ placement,
+ top,
+ width: inputPos.tooltipWidth,
+ pageYOffset: inputPos.pageYOffset
+ } as IPlacementData;
+ }
+
+ /**
+ * Returns tooltip position data (left / top arrow)
+ * @param {TooltipPlacement} placement (left, top, right, bottom)
+ * @returns {IPlacementData}
+ */
+ private getLeftTopPosition(placement: TooltipPlacement): IPlacementData {
+ let left = 0;
+ let top = 0;
+
+ const inputPos: ITooltipPositionParams = this.getPlacementInputParams();
+ switch (placement) {
+ case TooltipPlacement.Left:
+ left = inputPos.elemLeft - inputPos.tooltipWidth - inputPos.tooltipOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight / 2 - inputPos.arrowOffset;
+ break;
+
+ case TooltipPlacement.Right:
+ left = inputPos.elemLeft + inputPos.elemWidth + inputPos.tooltipOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight / 2 - inputPos.arrowOffset;
+ break;
+
+ case TooltipPlacement.Top:
+ left = inputPos.elemLeft + inputPos.elemWidth / 2 - inputPos.arrowOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset - inputPos.tooltipHeight - inputPos.tooltipOffset;
+ break;
+
+ case TooltipPlacement.Bottom:
+ left = inputPos.elemLeft + inputPos.elemWidth / 2 - inputPos.arrowOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight + inputPos.tooltipOffset;
+ break;
+ }
+
+ return {
+ height: inputPos.tooltipHeight,
+ left,
+ placement,
+ top,
+ width: inputPos.tooltipWidth,
+ pageYOffset: inputPos.pageYOffset
+ } as IPlacementData;
+ }
+
+ /**
+ * Returns tooltip position data (right / bottom arrow)
+ * @param {TooltipPlacement} placement (left, top, right, bottom)
+ * @returns {IPlacementData}
+ */
+ private getRightBottomPosition(placement: TooltipPlacement): IPlacementData {
+ let left = 0;
+ let top = 0;
+
+ const inputPos: ITooltipPositionParams = this.getPlacementInputParams();
+ switch (placement) {
+ case TooltipPlacement.Left:
+ left = inputPos.elemLeft - inputPos.tooltipWidth - inputPos.tooltipOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight / 2 - inputPos.tooltipHeight + inputPos.arrowOffset;
+ break;
+
+ case TooltipPlacement.Right:
+ left = inputPos.elemLeft + inputPos.elemWidth + inputPos.tooltipOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight / 2 - inputPos.tooltipHeight + inputPos.arrowOffset;
+ break;
+
+ case TooltipPlacement.Top:
+ left = inputPos.elemLeft + inputPos.elemWidth / 2 - inputPos.tooltipWidth + inputPos.arrowOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset - inputPos.tooltipHeight - inputPos.tooltipOffset;
+ break;
+
+ case TooltipPlacement.Bottom:
+ left = inputPos.elemLeft + inputPos.elemWidth / 2 - inputPos.tooltipWidth + inputPos.arrowOffset;
+ top = inputPos.elemTop + inputPos.pageYOffset + inputPos.elemHeight + inputPos.tooltipOffset;
+ break;
+ }
+
+ return {
+ height: inputPos.tooltipHeight,
+ left,
+ placement,
+ top,
+ width: inputPos.tooltipWidth,
+ pageYOffset: inputPos.pageYOffset
+ } as IPlacementData;
+ }
+
+ /**
+ * Checks if tooltip position is valid
+ * @param {IPlacementData} pos
+ * @returns {boolean}
+ */
+ private validatePosition(pos: IPlacementData): boolean {
+ if (pos.left < 0 || pos.left + pos.width - 1 > this.ScreenWidth) {
+ return false;
+ }
+
+ if (pos.top - pos.pageYOffset < 0 || pos.top - pos.pageYOffset + pos.height - 1 > this.ScreenHeight) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Scrolling
+ */
+
+ private debounce(func: Function, wait: number, immediate?: boolean) {
+ let timeout;
+ return function() {
+ const context = this;
+ const args = arguments;
+ const later = () => {
+ timeout = null;
+ if (!immediate) {
+ func.apply(context, args);
+ }
+ };
+ const callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) {
+ func.apply(context, args);
+ }
+ };
+ }
+
+ private initScrollEvent() {
+ this.scrollEventHandler = this.debounce(() => {
+ try {
+ this.setPosition();
+ } catch (e) {
+
+ }
+ }, 10);
+ }
+
+ private activateScrollEvent() {
+ window.addEventListener('scroll', this.scrollEventHandler , true);
+ }
+
+ private deactivateScrollEvent() {
+ window.removeEventListener('scroll', this.scrollEventHandler , true);
+ }
+}
+
+export enum TooltipPlacement {
+ Left,
+ Right,
+ Top,
+ Bottom
+}
+
+export enum ArrowPlacement {
+ CenterMiddle,
+ LeftTop,
+ RightBottom
+}
+
+interface ITooltipPositionParams {
+ elemLeft: number;
+ elemTop: number;
+ elemWidth: number;
+ elemHeight: number;
+ tooltipWidth: number;
+ tooltipHeight: number;
+ tooltipOffset: number;
+ pageYOffset: number;
+ arrowOffset: number;
+}
+
+interface IPlacementData {
+ left: number;
+ top: number;
+ width: number;
+ height: number;
+ pageYOffset: number;
+ placement?: TooltipPlacement;
+}
selector: 'custom-ellipsis',
template: `
<span
- sdc-tooltip
+ custom-tooltip
class="ellipsis"
[attr.data-tests-id]="dataTestId"
id="{{id}}"
data-toggle="toggle">
<label class="checkbox-label"
for="{{data?.dataTestId}}">{{data?.displayName}}</label>
+ <div *ngFor="let extraContent of data?.extraContents" class="form-conrtols">
+ <div [ngSwitch]="extraContent.type">
+ <upload-files *ngSwitchCase="'UPLOAD_FILE'" [uploadFilesModel]="extraContent" [form]="form"></upload-files>
+ </div>
+ </div>
</div>
.details-item label {
position: relative;
cursor: pointer;
+ float: left;
}
.details-item label:before {
export class FileFormControlComponent {
@Input() data: FileFormControl = null;
@Input() form: FormGroup;
- @ViewChild('fileUploader')
+ @ViewChild('fileUploader', {static: false})
fileUploader:ElementRef ;
onDelete(event, data, form) {
})
export class InputFormControlComponent{
- @ViewChild('customInput') element:ElementRef;
+ @ViewChild('customInput', {static: false}) element:ElementRef;
@Input() data: InputFormControl = null;
@Input() form: FormGroup;
})
};
- getSDNCControl = (instance: any): FormControlModel => {
+ getSDNCControl = (instance: any, extraContents? : object[]): FormControlModel => {
return new CheckboxFormControl({
controlName: SDN_C_PRE_LOAD,
displayName: 'SDN-C pre-load',
dataTestId: 'sdncPreLoad',
value: instance ? instance.sdncPreLoad : false,
- validations: [new ValidatorModel(ValidatorOptions.required, 'is required')]
+ validations: [new ValidatorModel(ValidatorOptions.required, 'is required')],
+ extraContents
})
};
placeHolder: (!isEcompGeneratedNaming) ? 'Instance name' : 'Automatically generated when not provided',
validations: validations,
isVisible : true,
- value : (!isEcompGeneratedNaming || (!_.isNil(instance) && !_.isNil(instance.instanceName)))
+ value : (!isEcompGeneratedNaming || (!_.isNil(instance) && !_.isNil(instance.instanceName) && instance.instanceName !== ""))
? this._basicControlGenerator.getDefaultInstanceName(instance, model) : null,
onKeypress : (event) => {
const pattern:RegExp = ControlGeneratorUtil.INSTANCE_NAME_REG_EX;
import {GenericFormService} from "../../generic-form.service";
import {FormBuilder} from "@angular/forms";
import {LogService} from "../../../../utils/log/log.service";
-import {FormControlModel, ValidatorModel, ValidatorOptions} from "../../../../models/formControlModels/formControl.model";
+import {
+ FormControlModel,
+ ValidatorModel,
+ ValidatorOptions
+} from "../../../../models/formControlModels/formControl.model";
import {FormControlNames, VfModuleControlGenerator} from "./vfModule.control.generator";
-import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flags.service";
+import {FeatureFlagsService, Features} from "../../../../services/featureFlag/feature-flags.service";
import {VfModuleInstance} from "../../../../models/vfModuleInstance";
import {VfModule} from "../../../../models/vfModule";
import {SharedControllersService} from "../sharedControlles/shared.controllers.service";
+import {AppState} from "../../../../store/reducers";
+import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
+import {instance, mock, when} from "ts-mockito";
+import each from "jest-each";
class MockAppStore<T> {
getState() {
let injector;
let service: VfModuleControlGenerator;
let httpMock: HttpTestingController;
+ let store : NgRedux<AppState>;
+ let mockFeatureFlagsService: FeatureFlagsService = mock(FeatureFlagsService);
+
beforeAll(done => (async () => {
TestBed.configureTestingModule({
AaiService,
FormBuilder,
LogService,
- {provide:FeatureFlagsService, useClass: MockFeatureFlagsService},
+ SharedTreeService,
+ {provide: FeatureFlagsService, useValue: instance(mockFeatureFlagsService)},
{provide: NgRedux, useClass: MockAppStore}]
});
await TestBed.compileComponents();
injector = getTestBed();
service = injector.get(VfModuleControlGenerator);
httpMock = injector.get(HttpTestingController);
+ store = injector.get(NgRedux);
jest.spyOn(console, 'error');
})().then(done).catch(done.fail));
+ let formControlsWithoutLcpRegionTenantLegacy : string[] =
+ [FormControlNames.INSTANCE_NAME,
+ FormControlNames.VOLUME_GROUP_NAME,
+ FormControlNames.ROLLBACK_ON_FAILURE,
+ SDN_C_PRE_LOAD,];
+
+ let formControlsWithLcpRegionTenantLegacy : string[] =
+ [FormControlNames.INSTANCE_NAME,
+ FormControlNames.VOLUME_GROUP_NAME,
+ FormControlNames.LCPCLOUD_REGION_ID,
+ FormControlNames.LEGACY_REGION,
+ FormControlNames.TENANT_ID,
+ FormControlNames.ROLLBACK_ON_FAILURE,
+ SDN_C_PRE_LOAD,];
+
+
+
test(' getMacroFormControls gets vnfStoreKey === null', () => {
const serviceId: string = "6e59c5de-f052-46fa-aa7e-2fca9d674c44";
const vnfStoreKey: string = null;
expect(console.error).toHaveBeenCalled();
});
- test('getAlaCarteFormControls should return the correct order of controls', () => {
+ each([
+ [true, 4, formControlsWithoutLcpRegionTenantLegacy],
+ [false, 7,formControlsWithLcpRegionTenantLegacy]
+ ]).
+ test('getAlaCarteFormControls should return the correct order of controls', (flag: boolean, controlAmount: number, orderedControls: string[]) => {
+ when(mockFeatureFlagsService.getFlagState(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(flag);
const controls:FormControlModel[] = getAlaCarteFormControls();
- const orderedControls : string[] = [
- FormControlNames.INSTANCE_NAME,
- FormControlNames.VOLUME_GROUP_NAME,
- FormControlNames.LCPCLOUD_REGION_ID,
- FormControlNames.LEGACY_REGION,
- FormControlNames.TENANT_ID,
- FormControlNames.ROLLBACK_ON_FAILURE,
- SDN_C_PRE_LOAD,
- ];
-
- expect(controls.length).toEqual(7);
+ expect(controls.length).toEqual(controlAmount);
for(let i = 0 ; i < orderedControls.length ; i++) {
expect(controls[i].controlName).toEqual(orderedControls[i]);
}
return controls;
}
- test('getAlaCarteFormControls responce with wrong order of controls', () => {
- const controls:FormControlModel[] = getAlaCarteFormControls();
-
- const orderedControls : string[] = [
- FormControlNames.INSTANCE_NAME,
- FormControlNames.VOLUME_GROUP_NAME,
- FormControlNames.LCPCLOUD_REGION_ID,
- FormControlNames.TENANT_ID, // TENANT_ID must be after LEGACY_REGION
- FormControlNames.LEGACY_REGION,
- FormControlNames.ROLLBACK_ON_FAILURE,
- SDN_C_PRE_LOAD,
- ];
-
- for(let i = 0 ; i < orderedControls.length ; i++) {
- if (controls[i].controlName === 'legacyRegion') {
- expect(orderedControls[i]).toEqual('tenantId');
- }
- }
- });
-
test('getMacroFormControls should return the correct order of controls', () => {
const serviceId: string = "6e59c5de-f052-46fa-aa7e-2fca9d674c44";
const vnfStoreKey: string = 'VF_vGeraldine 0';
expect(instanceNameValidator.validatorArg).toEqual(/^[a-zA-Z0-9._-]*$/);
});
- test(' getAlaCarteFormControls gets null service', () => {
- const controls:FormControlModel[] = getAlaCarteFormControls();
- expect(controls.length).toEqual(7);
- const orderedControls : string[] = [
- FormControlNames.INSTANCE_NAME,
- FormControlNames.VOLUME_GROUP_NAME,
- FormControlNames.LCPCLOUD_REGION_ID,
- FormControlNames.LEGACY_REGION,
- FormControlNames.TENANT_ID,
- FormControlNames.ROLLBACK_ON_FAILURE,
- SDN_C_PRE_LOAD,
- ];
+ test('when flag is active - response should contains upload file', ()=>{
+ spyOn(store, 'getState').and.returnValue( {
+ "global": {
+ "flags": {
+ "FLAG_2006_VFM_SDNC_PRELOAD_FILES" : true
+ }
+ }
+ });
+
+ const extraContent = service.getSdncExtraContents();
+ console.log("extraContent", extraContent);
+ const uploadFileData = <any>extraContent[0];
+
+ expect(uploadFileData.type).toEqual('UPLOAD_FILE');
+ expect(uploadFileData.dataTestId).toEqual('sdnc_pereload_upload_link');
+ expect(uploadFileData.uploadMethod).toBeDefined();
+ expect(uploadFileData.isDisabled).toBeDefined();
+ expect(uploadFileData.onSuccess).toBeDefined();
+ expect(uploadFileData.onFailed).toBeDefined();
+
+ })
- for(let i = 0 ; i < orderedControls.length ; i++) {
- expect(controls[i].controlName).toEqual(orderedControls[i]);
- }
- });
});
import {AaiService} from "../../../../services/aaiService/aai.service";
import {NgRedux} from "@angular-redux/store";
import {HttpClient} from "@angular/common/http";
-import {ControlGeneratorUtil} from "../control.generator.util.service";
+import {ControlGeneratorUtil, SDN_C_PRE_LOAD} from "../control.generator.util.service";
import {
CustomValidatorOptions,
FormControlModel,
import {VnfInstance} from "../../../../models/vnfInstance";
import * as _ from 'lodash';
import {SharedControllersService} from "../sharedControlles/shared.controllers.service";
+import {MessageModal} from "../../../messageModal/message-modal.service";
+import {ButtonType} from "../../../customModal/models/button.type";
+import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
+import {FeatureFlagsService, Features} from "../../../../services/featureFlag/feature-flags.service";
export enum FormControlNames {
INSTANCE_NAME = 'instanceName',
export class VfModuleControlGenerator {
aaiService: AaiService;
vfModuleModel: VfModule;
- isUpdateMode : boolean;
+ isUpdateMode: boolean;
constructor(private genericFormService: GenericFormService,
private _basicControlGenerator: ControlGeneratorUtil,
private _sharedControllersService: SharedControllersService,
+ private _sharedTreeService: SharedTreeService,
private store: NgRedux<AppState>,
private http: HttpClient,
private _aaiService: AaiService,
- private _logService: LogService) {
+ private _logService: LogService,
+ private _featureFlagsService:FeatureFlagsService) {
this.aaiService = _aaiService;
}
if (isUpdateMode && this.store.getState().service.serviceInstance[serviceId] &&
_.has(this.store.getState().service.serviceInstance[serviceId].vnfs, vnfStoreKey) &&
_.has(this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules, UUIDData['modelName'])) {
- vfModuleInstance = Object.assign({},this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules[UUIDData['modelName']][UUIDData['vFModuleStoreKey']]);
+ vfModuleInstance = Object.assign({}, this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey].vfModules[UUIDData['modelName']][UUIDData['vFModuleStoreKey']]);
}
return vfModuleInstance;
};
return vfModule;
}
- getMacroFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
+ getMacroFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData: Object, isUpdateMode: boolean): FormControlModel[] {
this.isUpdateMode = isUpdateMode;
this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
- if(isUpdateMode){
+ if (isUpdateMode) {
this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
return [];
}
const vfModuleInstance = this._basicControlGenerator.retrieveInstanceIfUpdateMode(this.store, this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode));
const vfModuleModel = this.vfModuleModel;
const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
- const vnfModelName: string = vnf.originalName;
- const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfModelName]);
+ const vnfModel = this.newVNFModel(serviceId, vnf);
let result: FormControlModel[] = [];
if (!_.isNil(vfModuleModel)) {
result = this.pushInstanceAndVGToForm(result, vfModuleInstance, serviceId, vnfModel, false);
}
- if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
+ if (this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
result = this._basicControlGenerator.concatSupplementaryFile(result, vfModuleInstance);
}
return result;
}
- pushInstanceAndVGToForm(result: FormControlModel[], vfModuleElement: any, serviceId: string, vnfModel: any, isALaCarte: boolean) :FormControlModel[]{
+ private newVNFModel(serviceId: string, vnf: VnfInstance) {
+ const vnfModelName: string = this._sharedTreeService.modelUniqueNameOrId(vnf);
+
+ const serviceModelFromHierarchy = this.store.getState().service.serviceHierarchy[serviceId];
+ const model = this._sharedTreeService.modelByIdentifiers(serviceModelFromHierarchy, "vnfs", vnfModelName);
+ return new VNFModel(model);
+ }
+
+ pushInstanceAndVGToForm(result: FormControlModel[], vfModuleElement: any, serviceId: string, vnfModel: any, isALaCarte: boolean): FormControlModel[] {
result.push(this.getInstanceName(vfModuleElement, serviceId, vnfModel.isEcompGeneratedNaming));
if (this.vfModuleModel.volumeGroupAllowed) {
result.push(this.getVolumeGroupData(vfModuleElement, serviceId, vnfModel.isEcompGeneratedNaming, isALaCarte));
return result;
}
- getAlaCarteFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData : Object, isUpdateMode: boolean): FormControlModel[] {
+ getAlaCarteFormControls(serviceId: string, vnfStoreKey: string, vfModuleStoreKey: string, uuidData: Object, isUpdateMode: boolean): FormControlModel[] {
this.isUpdateMode = isUpdateMode;
this.extractVfAccordingToVfModuleUuid(serviceId, uuidData);
if (_.isNil(serviceId) || _.isNil(vnfStoreKey) || _.isNil(vfModuleStoreKey)) {
- if(isUpdateMode){
+ if (isUpdateMode) {
this._logService.error('should provide serviceId, vfModuleStoreKey, vnfStoreKey', serviceId);
return [];
}
}
- const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey] ;
- const vnfModelName: string = vnf.originalName;
- const vnfModel = new VNFModel(this.store.getState().service.serviceHierarchy[serviceId].vnfs[vnfModelName]);
+ const vnf: VnfInstance = this.store.getState().service.serviceInstance[serviceId].vnfs[vnfStoreKey];
+ const vnfModel = this.newVNFModel(serviceId, vnf);
const vfModuleInstance = this._basicControlGenerator.retrieveInstanceIfUpdateMode(this.store, this.getVfModuleInstance(serviceId, vnfStoreKey, uuidData, isUpdateMode));
let result: FormControlModel[] = [];
this.pushInstanceAndVGToForm(result, vfModuleInstance, serviceId, vnfModel, true);
- result.push(this._sharedControllersService.getLcpRegionControl(serviceId, vfModuleInstance, result));
- result.push(this._sharedControllersService.getLegacyRegion(vfModuleInstance));
- result.push(this._sharedControllersService.getTenantControl(serviceId, vfModuleInstance));
+ if( !this._featureFlagsService.getFlagState(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)) {
+ result.push(this._sharedControllersService.getLcpRegionControl(serviceId, vfModuleInstance, result));
+ result.push(this._sharedControllersService.getLegacyRegion(vfModuleInstance));
+ result.push(this._sharedControllersService.getTenantControl(serviceId, vfModuleInstance));
+ }
result.push(this._sharedControllersService.getRollbackOnFailureControl(vfModuleInstance));
- result.push(this._sharedControllersService.getSDNCControl(vfModuleInstance));
- if(this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
+ result.push(this._sharedControllersService.getSDNCControl(vfModuleInstance, this.getSdncExtraContents()));
+ if (this.store.getState().global.flags['FLAG_SUPPLEMENTARY_FILE']) {
result = this._basicControlGenerator.concatSupplementaryFile(result, vfModuleInstance);
}
return result;
}
- getInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): FormControlModel {
- let formControlModel:FormControlModel = this._sharedControllersService.getInstanceNameController(instance, serviceId, isEcompGeneratedNaming, this.vfModuleModel);
- formControlModel.onBlur = (event, form : FormGroup) => {
- if(!_.isNil(form.controls['volumeGroupName'])&& event.target.value.length > 0){
- form.controls['volumeGroupName'].setValue(event.target.value + "_vol");
+ getSdncExtraContents() : object[] {
+ return _.compact([
+ !!this.store.getState().global.flags['FLAG_2006_VFM_SDNC_PRELOAD_FILES'] ? {
+ type: 'UPLOAD_FILE',
+ dataTestId: 'sdnc_pereload_upload_link',
+ uploadMethod: (form: FormGroup) : Promise<boolean> => {
+ // this -> files item
+ return this._aaiService.sdncPreload().toPromise()
+ .then((response : boolean)=>{
+ return response;
+ }).catch(err => {
+ return false;
+ });
+ },
+ isDisabled: (form: FormGroup): boolean => {
+ return !form.controls[SDN_C_PRE_LOAD].value;
+ },
+ onSuccess: (form: FormGroup): void => {
+ MessageModal.showMessageModal({
+ text: 'The pre-load file(s) have been uploaded successfully.',
+ type: "success",
+ title: 'Success',
+ buttons: [{type: ButtonType.success, size: 'large', text: 'OK', closeModal: true}]
+ })
+ },
+ onFailed: (form: FormGroup) : void=> {
+ MessageModal.showMessageModal({
+ text: 'Failed to upload one or more of the files, please retry.',
+ type: "error",
+ title: 'Failure',
+ buttons: [{type: ButtonType.error, size: 'large', text: 'OK', closeModal: true}]
+ })
}
- };
+ } : null
+ ]);
+ }
+
+
+ getInstanceName(instance: any, serviceId: string, isEcompGeneratedNaming: boolean): FormControlModel {
+ let formControlModel: FormControlModel = this._sharedControllersService.getInstanceNameController(instance, serviceId, isEcompGeneratedNaming, this.vfModuleModel);
+ formControlModel.onBlur = (event, form: FormGroup) => {
+ if (!_.isNil(form.controls['volumeGroupName']) && event.target.value.length > 0) {
+ form.controls['volumeGroupName'].setValue(event.target.value + "_vol");
+ }
+ };
return formControlModel;
}
getDefaultVolumeGroupName(instance: any, isEcompGeneratedNaming: boolean): string {
- if ((!_.isNil(instance) && instance.volumeGroupName)) {
+ if ((!_.isNil(instance) && instance.volumeGroupName)) {
return instance.volumeGroupName;
}
if (isEcompGeneratedNaming) {
displayName: 'Volume Group Name',
dataTestId: 'volumeGroupName',
validations: validations,
- tooltip : 'When filled, VID will create a Volume Group by this name and associate with this module.\n' +
- 'When empty, the module is created without a Volume Group.',
- isVisible: this.shouldVGNameBeVisible(isEcompGeneratedNaming,isALaCarte),
+ tooltip: 'When filled, VID will create a Volume Group by this name and associate with this module.\n' +
+ 'When empty, the module is created without a Volume Group.',
+ isVisible: this.shouldVGNameBeVisible(isEcompGeneratedNaming, isALaCarte),
value: this.getDefaultVolumeGroupName(instance, isEcompGeneratedNaming),
onKeypress: (event) => {
- const pattern:RegExp = ControlGeneratorUtil.INSTANCE_NAME_REG_EX;
+ const pattern: RegExp = ControlGeneratorUtil.INSTANCE_NAME_REG_EX;
if (pattern) {
if (!pattern.test(event['key'])) {
event.preventDefault();
}
private shouldVGNameBeVisible(isEcompGeneratedNaming: boolean, isALaCarte: boolean) {
- if((!isALaCarte && !isEcompGeneratedNaming) || isALaCarte){
+ if ((!isALaCarte && !isEcompGeneratedNaming) || isALaCarte) {
return true;
}
return false;
FormControlNames.INSTANCE_NAME,
FormControlNames.LCPCLOUD_REGION_ID,
FormControlNames.TENANT_ID,
- 'platformName'
+ 'platformName',
+ FormControlNames.PRODUCT_FAMILY_ID
];
for(let i = 0 ; i < mandatoryControls.length ; i++){
if (!_.isNil(vnfModel)) {
result.push(this.getInstanceName(vnfInstance, serviceId, vnfName, vnfModel.isEcompGeneratedNaming));
- result.push(this._sharedControllersService.getProductFamilyControl(vnfInstance, result, false));
+ result.push(this._sharedControllersService.getProductFamilyControl(vnfInstance, result, true));
result.push(this._sharedControllersService.getLcpRegionControl(serviceId, vnfInstance, result));
result.push(this._sharedControllersService.getLegacyRegion(vnfInstance));
result.push(this._sharedControllersService.getTenantControl(serviceId, vnfInstance));
if (!_.isNil(vnfModel)) {
const flags = this.store.getState().global.flags;
result.push(this.getInstanceName(vnfInstance, serviceId, vnfName, vnfModel.isEcompGeneratedNaming));
- result.push(this._sharedControllersService.getProductFamilyControl(vnfInstance, result, false));
+ result.push(this._sharedControllersService.getProductFamilyControl(vnfInstance, result, true));
result.push(this._sharedControllersService.getLcpRegionControl(serviceId, vnfInstance, result));
result.push(this._sharedControllersService.getLegacyRegion(vnfInstance));
result.push(this._sharedControllersService.getTenantControl(serviceId, vnfInstance));
<div *ngFor="let formControl of formControls" class="form-conrtols">
<div [ngSwitch]="formControl.type">
<form-control-input *ngSwitchCase="'INPUT'" [data]="formControl" [form]="dynamicFormGroup"></form-control-input>
- <checkbox-form-control *ngSwitchCase="'CHECKBOX'" [data]="formControl" [form]="dynamicFormGroup" ></checkbox-form-control>
+ <checkbox-form-control *ngSwitchCase="'CHECKBOX'" [data]="formControl" [form]="dynamicFormGroup"></checkbox-form-control>
<dropdown-form-control *ngSwitchCase="'DROPDOWN'" [data]="formControl" [form]="dynamicFormGroup" ></dropdown-form-control>
<file-form-control *ngSwitchCase="'FILE'" [data]="formControl" [form]="dynamicFormGroup"></file-form-control>
<multiselect-form-control *ngSwitchCase="'MULTI_SELECT'"
--- /dev/null
+<div>
+ <a [attr.data-tests-id]="uploadFilesModel.dataTestId"
+ (click)="uploadFilesTrigger()"
+ href="javascript:void(0)"
+ class="upload-text"
+ [class.disabled]="uploadFilesModel.isDisabled && uploadFilesModel.isDisabled(form)">{{uploadFilesModel.uploadText || 'Upload'}}</a>
+ <span class="hide-span">
+ <input
+ type="file"
+ #fileInput
+ ng2FileSelect
+ [uploader]="uploader"
+ [attr.data-tests-id]="uploadFilesModel.dataTestId + '-input'"/>
+ </span>
+</div>
--- /dev/null
+.upload-text {
+ margin-left: 30px;
+ font-family: OpenSans-Semibold;
+ font-size: 14px;
+ line-height: 23px;
+}
+
+a.disabled {
+ color: gray;
+ cursor: not-allowed;
+ text-decoration: underline;
+}
+
+.hide-span {
+ visibility: hidden;
+ position: absolute;
+ overflow: hidden;
+ width: 0px;
+ height: 0px;
+ border: none;
+ margin: 0;
+ padding: 0
+}
--- /dev/null
+import {Component, ElementRef, Input, OnInit, ViewChild} from "@angular/core";
+import {FileItem, FileUploader} from "ng2-file-upload";
+import {UploadFilesLinkModel} from "./upload-files-link.model";
+import {FormGroup} from "@angular/forms";
+
+@Component({
+ selector: 'upload-files',
+ templateUrl: './upload-files-link.component.html',
+ styleUrls: ['./upload-files-link.component.scss']
+})
+export class UploadFilesLinkComponent implements OnInit {
+ uploader: FileUploader;
+ @Input() uploadFilesModel: UploadFilesLinkModel;
+ @Input() form: FormGroup;
+ @ViewChild('fileInput', {static: false}) fileInput: ElementRef;
+
+ ngOnInit(): void {
+ this.uploader = new FileUploader({});
+
+ this.uploader.onAfterAddingAll = async (files: FileItem[]) => {
+ const result = await this.uploadFilesModel.uploadMethod.call(files, this.form);
+ if (result && this.uploadFilesModel.onSuccess) {
+ this.uploadFilesModel.onSuccess.call(this.form);
+ } else if (!result && this.uploadFilesModel.onFailed) {
+ this.uploadFilesModel.onFailed.call(this.form);
+ }
+ this.uploadFilesModel.uploadText = result ? 'Upload another' : 'Upload'
+ };
+ this.resetUpload();
+ }
+
+ resetUpload(): void {
+ this.fileInput.nativeElement.value = '';
+ }
+
+ uploadFilesTrigger() {
+ if (this.uploadFilesModel.isDisabled && !this.uploadFilesModel.isDisabled(this.form)) {
+ this.fileInput.nativeElement.click();
+ }
+ }
+}
--- /dev/null
+import {FileItem} from "ng2-file-upload";
+
+export class UploadFilesLinkModel {
+ uploadText?: string;
+
+ /*********************************************************************
+ Implement success method - run after uploadMethod return true result
+ **********************************************************************/
+ onSuccess?: (...args) => void;
+
+ /*********************************************************************
+ Implement failed method - run after uploadMethod return false result
+ **********************************************************************/
+ onFailed?: (...args) => void;
+
+ /*********************************************************************************
+ Implement upload method and return the upload result status (false/true)
+ *********************************************************************************/
+ uploadMethod: (file: FileItem[], ...args) => Promise<boolean>;
+
+ /********************************
+ Should upload file be disabled
+ ********************************/
+ isDisabled?: (...args) => boolean;
+
+ /********************************
+ a tag data test id
+ ********************************/
+ dataTestId : string;
+}
type="button" class="btn btn-success submit"
(click)="openTemplateModal()"
><span>Template</span></button>
- <button
- *ngIf="isShowPreviousInstantiationBtn"
- [attr.data-tests-id]="'ShowPreviousInstancesButton'"
- type="button" class="btn btn-success submit"
- (click)="formPopupDetails.onOtherAction(formPopupDetails.that, dynamicForm)"
- ><span>Previous Instantiation</span></button>
<button
[attr.data-tests-id]="'cancelButton'"
type="button" class="btn btn-default cancel"
type: PopupType;
uuidData: UUIDData;
showTemplateBtn: boolean = false;
- isShowPreviousInstantiationBtn: boolean = false;
isUpdateMode: boolean;
node: ITreeNode = null;
hasGeneralApiError: boolean = false;
.subscribe(params => {
this.serviceModelId = params['serviceModelId'];
if (this.serviceModelId && params['isCreate'] == "true") {
- this.onInitForCreateNewServicePopup(params['hasTemplate']);
+ this.onInitForCreateNewServicePopup(params['isInstantiationTemplateExists']);
}
});
}
}
- private onInitForCreateNewServicePopup(hasTemplate : boolean) {
+ private onInitForCreateNewServicePopup(isInstantiationTemplateExists : boolean) {
this._genericFormPopupService.initReduxOnCreateNewService().then((serviceModelId: string) => {
this.uuidData = <any>{
bulkSize: 1,
popupService: this._servicePopupService,
};
- this.showTemplateBtn = this._genericFormPopupService.shouldShowTemplateBtn(hasTemplate);
- this.isShowPreviousInstantiationBtn = !!this._store.getState().global.flags["FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER"];
+ this.showTemplateBtn = this._genericFormPopupService.shouldShowTemplateBtn(isInstantiationTemplateExists);
this.uuidData.popupService.closeDialogEvent.subscribe((that) => {
this.closeDialog(that);
import {SharedControllersService} from "../genericForm/formControlsServices/sharedControlles/shared.controllers.service";
import {AppState} from "../../store/reducers";
import each from 'jest-each';
+import {SharedTreeService} from "../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
class MockAppStore<T>{
getState() {
VfModuleUpgradePopupService,
VfModuleControlGenerator,
FeatureFlagsService,
+ SharedTreeService,
{provide: ActivatedRoute, useClass: ActivatedRouteMock},
{provide: NgRedux, useClass: MockAppStore}]
});
const shouldShowTemplateBtnDataProvider = [
- ['shouldShowTemplateBtn : should return true if flag is true and has template', true , true, true],
- ['shouldShowTemplateBtn : should return false if flag is false and has template',false , true, false],
- ['shouldShowTemplateBtn : should return false if flag is true and has no template',true , false, false],
- ['shouldShowTemplateBtn : should return false if flag is false and has no template',false , false, false]];
- each(shouldShowTemplateBtnDataProvider).test('%s', (desc : string, flag : boolean, hasTemplate : boolean, expected : boolean ) => {
+ ['shouldShowTemplateBtn : should return true if flag is true and has instantiation template', true , true, true],
+ ['shouldShowTemplateBtn : should return false if flag is false and has instantiation template',false , true, false],
+ ['shouldShowTemplateBtn : should return false if flag is true and has no instantiation template',true , false, false],
+ ['shouldShowTemplateBtn : should return false if flag is false and has no instantiation template',false , false, false]];
+ each(shouldShowTemplateBtnDataProvider).test('%s', (desc : string, flag : boolean, isInstantiationTemplateExists : boolean, expected : boolean ) => {
spyOn(_featureFlagsService, 'getFlagState').and.returnValue(flag)
- const result: boolean = service.shouldShowTemplateBtn(hasTemplate);
+ const result: boolean = service.shouldShowTemplateBtn(isInstantiationTemplateExists);
expect(result).toEqual(expected);
});
});
- shouldShowTemplateBtn = (hasTemplate: boolean) : boolean => {
+ shouldShowTemplateBtn = (isInstantiationTemplateExists: boolean) : boolean => {
const instantiationTemplateFlag = this._featureFlagsService.getFlagState(Features.FLAG_2004_INSTANTIATION_TEMPLATES_POPUP);
if(instantiationTemplateFlag){
- return hasTemplate;
+ return isInstantiationTemplateExists;
}
return false;
}
import {DefaultDataGeneratorService} from "../../../services/defaultDataServiceGenerator/default.data.generator.service";
import {FormControlModel} from "../../../models/formControlModels/formControl.model";
import {BasicPopupService} from "./basic.popup.service";
-import {SdcUiServices} from "onap-ui-angular";
import {FeatureFlagsService} from "../../../services/featureFlag/feature-flags.service";
import {getTestBed, TestBed} from "@angular/core/testing";
+import {ModalService} from "../../customModal/services/modal.service";
class MockAppStore<T> {}
{provide:FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockReduxStore},
{provide: HttpClient, useClass: MockAppStore},
- {provide: SdcUiServices.ModalService, useClass: MockModalService}
+ {provide: ModalService, useClass: MockModalService}
]
});
await TestBed.compileComponents();
import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flags.service";
import {getTestBed, TestBed} from "@angular/core/testing";
import {SharedControllersService} from "../../../genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../customModal/services/modal.service";
class MockAppStore<T> {}
{provide:FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockReduxStore},
{provide: HttpClient, useClass: MockAppStore},
- {provide: SdcUiServices.ModalService, useClass: MockModalService}
+ {provide: ModalService, useClass: MockModalService}
]
});
await TestBed.compileComponents();
import {ServicePopupService} from "./service.popup.service";
import {ServiceControlGenerator} from "../../../genericForm/formControlsServices/service.control.generator";
import {FormControlModel} from "../../../../models/formControlModels/formControl.model";
-import {SdcUiServices} from "onap-ui-angular";
import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flags.service";
import {getTestBed, TestBed} from "@angular/core/testing";
import {SharedControllersService} from "../../../genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../customModal/services/modal.service";
class MockModalService<T> {}
{provide:FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockReduxStore},
{provide: HttpClient, useClass: MockAppStore},
- {provide: SdcUiServices.ModalService, useClass: MockModalService}
+ {provide: ModalService, useClass: MockModalService}
]
});
await TestBed.compileComponents();
expect(service.closeDialogEvent.next).toHaveBeenCalledWith(that);
});
- test('showPreviousInstantiations should trigger postMessage', () => {
- let that = <any>{
- parentElementClassName: 'content',
- _iframeService: iframeService,
- resetPopupData : () =>{ },
- serviceModel:{
- uuid:'1111'
- }
-
- };
-
- let expectedMessage= {
- eventId: 'showPreviousInstantiations',
- data: {
- serviceModelId: that.serviceModel.uuid
- }
- };
-
- jest.spyOn(window.parent, 'postMessage');
-
- service.showPreviousInstantiations(that, fb.group({}));
-
- expect( window.parent.postMessage).toHaveBeenCalledWith(expectedMessage,"*")
-
- });
-
-
test('getDynamicInputs should return list of controls' ,() => {
const result: FormControlModel[] = service.getDynamicInputs('6b528779-44a3-4472-bdff-9cd15ec93450');
(that, form: FormGroup) => {that.onSubmit(that, form);},
(that: any, form: FormGroup) => {
that.onCancel(that, form);
- },
- (that: any, form: FormGroup) => {
- that.showPreviousInstantiations(that, form);
}
);
}
this.onCancel(that, form);
}
- showPreviousInstantiations(that, form: FormGroup,): void {
- const eventId = 'showPreviousInstantiations';
- this.postMessageToWindowParent(eventId, that.serviceModel.uuid);
- this.onCancel(that, form);
- }
-
private postMessageToWindowParent(eventId: string, serviceModelId:string) {
window.parent.postMessage({
eventId: eventId,
import {BasicPopupService} from "../basic.popup.service";
import {VfModulePopupService} from "./vfModule.popup.service";
import {VfModuleControlGenerator} from "../../../genericForm/formControlsServices/vfModuleGenerator/vfModule.control.generator";
-import {SdcUiServices} from "onap-ui-angular";
import {FeatureFlagsService} from "../../../../services/featureFlag/feature-flags.service";
import {getTestBed, TestBed} from "@angular/core/testing";
import {SharedControllersService} from "../../../genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../customModal/services/modal.service";
+import {SharedTreeService} from "../../../../../drawingBoard/service-planning/objectsToTree/shared.tree.service";
class MockModalService<T> {}
AaiService,
LogService,
BasicPopupService,
+ SharedTreeService,
{provide:FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockReduxStore},
{provide: HttpClient, useClass: MockAppStore},
- {provide: SdcUiServices.ModalService, useClass: MockModalService}
+ {provide: ModalService, useClass: MockModalService}
]
});
await TestBed.compileComponents();
import {LogService} from "../../../../utils/log/log.service";
import {NgRedux} from "@angular-redux/store";
-import {
- ControlGeneratorUtil,
- SDN_C_PRE_LOAD,
- SUPPLEMENTARY_FILE
-} from "../../../genericForm/formControlsServices/control.generator.util.service";
+import {ControlGeneratorUtil, SDN_C_PRE_LOAD, SUPPLEMENTARY_FILE} from "../../../genericForm/formControlsServices/control.generator.util.service";
import {AaiService} from "../../../../services/aaiService/aai.service";
import {HttpClient} from "@angular/common/http";
import {GenericFormService} from "../../../genericForm/generic-form.service";
import {FormControlModel} from "../../../../models/formControlModels/formControl.model";
import * as _ from "lodash";
import {SharedControllersService} from "../../../genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {ModalService} from "../../../customModal/services/modal.service";
class MockModalService<T> {}
{provide: FeatureFlagsService, useClass: MockFeatureFlagsService},
{provide: NgRedux, useClass: MockReduxStore},
{provide: HttpClient, useClass: MockAppStore},
- {provide: SdcUiServices.ModalService, useClass: MockModalService}
+ {provide: ModalService, useClass: MockModalService}
]
});
await TestBed.compileComponents();
};
form.controls = {
supplementaryFile_hidden_content : {
- value: '{"c": "c", "d": 1}'
+ value: '[{"name": "c", "value": "c"}, {"name": "d", "value": "1"}]'
},
supplementaryFile_hidden : {
value: {
let expectedMergePayload = {
a: "value",
b: "another",
- supplementaryFileContent: {c: "c", d: 1},
+ supplementaryFileContent: [{"name": "c", "value": "c"}, {"name": "d", "value": "1"}],
supplementaryFileName: "name"
};
<th class="header-title" id="header-summary">Summary</th>
<th class="header-title" id="header-region">Region</th>
<th class="header-title" id="header-tenant">Tenant</th>
- <th class="header-title" id="header-aicZone">AIC Zone</th>
</tr>
</thead>
<tbody>
</custom-ellipsis>
</div>
</td>
- <td>
- <div>
- <custom-ellipsis
- [dataTestId]="'aicZone-' + item.jobId"
- [id]="item.aicZone"
- [value]="item.aicZone"
- [breakWord]="true">
- </custom-ellipsis>
- </div>
- </td>
</tr>
</tbody>
</table>
}
}
-//
-
-
class MockAppStore {}
describe('instantiation templates modal service', () => {
expect(tableRows[0].instantiationStatus).toEqual('FAILED');
expect(tableRows[0].region).toEqual('hvf6 (AAA1)');
expect(tableRows[0].tenant).toEqual('AIN Web Tool-15-D-SSPtestcustome');
- expect(tableRows[0].aicZone).toEqual('VSDKYUTP-BAN1');
expect(tableRows[0].jobId).toEqual('9f88fdb5-bb47-4bf3-8c5f-98f1ad0ec87c');
});
expect(result.region).toEqual('regionId (OWNER)');
});
+ test('getRegion if null should return empty string', () => {
+ let result: InstantiationTemplatesRowModel = new InstantiationTemplatesRowModel({
+ owningEntityName: 'att-owner',
+ regionId: null
+ });
+ expect(result.region).toEqual('(OWNER)');
+ });
+
test('getCloudOwner should not return owningEntityName if not exist', () => {
let result: InstantiationTemplatesRowModel = new InstantiationTemplatesRowModel({owningEntityName: null, regionId: 'regionId'});
expect(result.region).toEqual('regionId');
service.navigateToNewServiceModal(serviceModelId);
- expect(_router.navigate).toBeCalledWith(["/servicePopup"], {"queryParams": {"isCreate": true, "serviceModelId": serviceModelId, hasTemplate : true}, "queryParamsHandling": "merge"});
+ expect(_router.navigate).toBeCalledWith(["/servicePopup"], {"queryParams": {"isCreate": true, "serviceModelId": serviceModelId, isInstantiationTemplateExists : true}, "queryParamsHandling": "merge"});
})
});
navigateToNewServiceModal(serviceModelId: string) {
- this._router.navigate(['/servicePopup'], { queryParams: { serviceModelId: serviceModelId, isCreate:true, hasTemplate : true}, queryParamsHandling: 'merge' });
+ this._router.navigate(['/servicePopup'], { queryParams: { serviceModelId: serviceModelId, isCreate:true, isInstantiationTemplateExists : true}, queryParamsHandling: 'merge' });
}
}
readonly summary?: string;
readonly region?: string;
readonly tenant?: string;
- readonly aicZone?: string;
constructor(data) {
super(data);
this.summary = this.convertRequestSummaryFromMapToString(data.requestSummary);
this.region = this.getRegion(data.regionId, data.owningEntityName);
this.tenant = !_.isNil(data.tenantName) ? data.tenantName : null;
- this.aicZone = !_.isNil(data.aicZoneName) ? data.aicZoneName : null;
}
getRegion = (regionId: string, owningEntityName: string): string => {
const convertOwning = !_.isNil(owningEntityName) ? `(${this.getCloudOwner(owningEntityName)})` : '';
- return `${regionId} ${convertOwning}`.trim();
+ const region = !_.isNil(regionId) ? regionId : '';
+ return `${region} ${convertOwning}`.trim();
};
import { Component } from '@angular/core';
import { MessageBoxData} from './messageBox.data';
import { MessageBoxService } from './messageBox.service';
-import { SdcUiServices} from "onap-ui-angular";
+import {ModalService} from "../customModal/services/modal.service";
@Component({
selector: 'message-box',
})
export class MessageBoxComponent {
- modalService: SdcUiServices.ModalService;
+ modalService: ModalService;
isOpened : boolean = false;
- constructor(modalService: SdcUiServices.ModalService, private _messageBoxService : MessageBoxService) {
+ constructor(modalService: ModalService, private _messageBoxService : MessageBoxService) {
this.modalService = modalService;
MessageBoxService.openModal.subscribe((messageBoxData: MessageBoxData) => {
--- /dev/null
+import {ButtonType} from "../customModal/models/button.type";
+
+export class MessageModalModel {
+ title : string;
+ text : string;
+ type : 'error' | 'info' | 'success';
+ buttons : {text: string, size: string, type : ButtonType, closeModal: boolean}[];
+
+ constructor( title : string, text : string, type , buttons : {text: string, size: string, type : ButtonType, closeModal: boolean}[]){
+ this.title = title;
+ this.text = text;
+ this.type = type;
+ this.buttons = buttons;
+ }
+}
--- /dev/null
+import {MessageModal} from "./message-modal.service";
+import {getTestBed, TestBed} from "@angular/core/testing";
+import {SdcUiCommon} from "onap-ui-angular";
+import each from "jest-each";
+import {MessageBoxService} from "../messageBox/messageBox.service";
+import {MessageModalModel} from "./message-modal.model";
+import {MessageBoxData} from "../messageBox/messageBox.data";
+
+
+describe('Message Modal Service', () => {
+ let injector;
+ let service: MessageModal;
+
+ beforeAll(done => (async () => {
+ TestBed.configureTestingModule({
+ imports: [],
+ providers: [MessageModal]
+ });
+ await TestBed.compileComponents();
+
+ injector = getTestBed();
+ service = injector.get(MessageModal);
+ })().then(done).catch(done.fail));
+
+
+ each([
+ ["error", SdcUiCommon.ModalType.error],
+ ["info", SdcUiCommon.ModalType.info],
+ ["success", SdcUiCommon.ModalType.success]
+ ]).test('getModalType with type %s should return %s', (inputMessageType, expectedResult) => {
+
+ let message = {
+ type: inputMessageType
+ };
+
+ const type = MessageModal.getModalType(<any>message)
+ expect(type).toEqual(expectedResult);
+ });
+
+ test('showMessageModal should call open modal with all data' , async (done)=>{
+ spyOn(MessageBoxService.openModal, 'next');
+ let message : MessageModalModel = new MessageModalModel('title', 'text', "success", []);
+
+ MessageModal.showMessageModal(message);
+ setTimeout(()=>{
+ const messageBoxData = new MessageBoxData( message.title,
+ message.text,
+ SdcUiCommon.ModalType.success,
+ SdcUiCommon.ModalSize.medium,
+ message.buttons)
+ expect(MessageBoxService.openModal.next).toHaveBeenCalledWith(messageBoxData);
+ done();
+ }, 500)
+ });
+
+});
--- /dev/null
+import {Injectable} from "@angular/core";
+import {MessageBoxService} from '../messageBox/messageBox.service';
+import {MessageBoxData} from '../messageBox/messageBox.data';
+import {SdcUiCommon} from "onap-ui-angular";
+import {MessageModalModel} from "./message-modal.model";
+
+@Injectable()
+export class MessageModal {
+ static showMessageModal(message: MessageModalModel): void {
+ setTimeout(() => {
+ let messageBoxData: MessageBoxData = new MessageBoxData(
+ message.title,
+ message.text,
+ this.getModalType(message),
+ SdcUiCommon.ModalSize.medium,
+ message.buttons);
+ MessageBoxService.openModal.next(messageBoxData);
+ }
+ , 500);
+ };
+
+
+ static getModalType = (message: MessageModalModel): string => {
+ switch (message.type) {
+ case "error": {
+ return SdcUiCommon.ModalType.error
+ }
+ case "info": {
+ return SdcUiCommon.ModalType.info;
+ }
+ case "success": {
+ return SdcUiCommon.ModalType.success;
+ }
+ }
+ };
+}
+
+
+
})
}
- @ViewChild('ElementsTableComponent') membersTable;
+ @ViewChild('ElementsTableComponent', {static: false}) membersTable;
ngOnInit(selectedRowsIds?: string[]): void {
const genericModalHelper = this._store.getState().global.genericModalHelper;
-<sdc-loader name= "global"
+<custom-loader name= "global"
#globalLoader
[global] = "global"
[size]="size"
- [(active)] = "show"></sdc-loader>
+ [(active)] = "show"></custom-loader>
@Component({
selector : 'vid-svg-icon',
- template: `
- <svg-icon
+ template: `
+ <custom-icon
[mode]="mode"
[size]="size"
[name]="name"
[testId]="testId"
[clickable]="clickable">
- </svg-icon>
+ </custom-icon>
`,
import {FormControlModel} from "./formControl.model";
import {FormControlType} from "./formControlTypes.enum";
+import * as _ from "lodash";
export class CheckboxFormControl extends FormControlModel{
-
+ extraContents : object[];
constructor(data) {
super(data);
this.type = FormControlType.CHECKBOX;
this.validations = [];
+ this.extraContents = !_.isNil(data.extraContents) ? data.extraContents : null;
}
}
this.preventionsAttribute = data.preventionsAttribute || [];
this.onBlur = function(){};
this.onChange = data.onChange ? data.onChange: function () {}
+
}
isRequired() : boolean {
modelInformationItems: ModelInformationItem[];
onSubmit : (that : any, form: FormGroup , ...args) => void;
onCancel : (that : any, form: FormGroup) => void;
- onOtherAction: (that: any, form: FormGroup) => void;
-
constructor(that : any,
popupTypeName : PopupType ,
dynamicInputsControlList : FormControlModel[],
modelInformationItems : ModelInformationItem[],
onSubmit : (that : any, form : FormGroup, ...args) => void,
- onCancel: (that: any, form: FormGroup) => void,
- onOtherAction?: (that: any, form: FormGroup) => void) {
+ onCancel: (that: any, form: FormGroup) => void) {
this.title = title;
this.leftSubTitle = leftSubTitle;
this.rightSubTitle = rightSubTitle;
this.modelInformationItems = modelInformationItems;
this.onSubmit = onSubmit;
this.onCancel = onCancel;
- this.onOtherAction = onOtherAction;
this.popupTypeName = popupTypeName;
this.UUIDData = UUIDData;
this.that = that;
import {ServiceNodeTypes} from "./ServiceNodeTypes";
import * as _ from 'lodash';
import {ServiceInstanceActions} from "./serviceInstanceActions";
+
export enum TreeLevel {
Level_0 , Level_1, Level_2
export class TreeNodeModel {
type: String;
modelId: string;
+ modelInvariantId?: string;
modelCustomizationId?: string;
modelUniqueId?: string;
id: string;
instanceName?: string;
constructor(instance: ChildNodeInstance, nodeModel: NodeModel){
+ this.modelInvariantId = nodeModel.invariantUuid;
this.modelCustomizationId = nodeModel.customizationUuid;
this.modelId = nodeModel.uuid;
this.modelUniqueId = this.modelCustomizationId || this.modelId;
updateProductFamilies, updateUserId
} from "../../storeUtil/utils/general/general.actions";
import {createServiceInstance} from "../../storeUtil/utils/service/service.actions";
-import {delay, mapTo} from "rxjs/operators";
const notFetchedAlready = (state: AppState): boolean => state.service.productFamilies !== null;
export class AAIEpics {
constructor(private aaiService: AaiService) {
}
-
public createEpic() {
return combineEpics(
this.loadProductFamiliesEpic
private loadProductFamiliesEpic = (action$, store) => action$
.ofType(LOAD_PRODUCT_FAMILIES)
- .switchMap(() => this.aaiService.getProductFamilies().map(data => updateProductFamilies(data)));
+ .switchMap(() =>
+ this.aaiService.getProductFamilies()
+ .map(data =>
+ updateProductFamilies(data)
+ ));
private loadCategoryParameters = (action$, store) => action$
.ofType(LOAD_CATEGORY_PARAMETERS)
private loadServiceAccordingToUuid = (action$, store) => action$
.ofType(LOAD_SERVICE_MDOEL_BY_UUID)
.switchMap((action) => this.aaiService.getServiceModelById(action.modelId)
- .map(data => createServiceInstance(action.uuid, data)));
+ .map(data =>
+ createServiceInstance(action.uuid, data))
+ );
private loadUserId = (action$, store) => action$
.ofType(LOAD_USER_ID)
}
+ sdncPreload(): Observable<boolean> {
+ let pathQuery: string = Constants.Path.PRE_LOAD;
+ return this.http.post<boolean>(pathQuery, {})
+ }
+
getServiceModelById = (serviceModelId: string): Observable<any> => {
if (_.has(this.store.getState().service.serviceHierarchy, serviceModelId)) {
return of(<any> JSON.parse(JSON.stringify(this.store.getState().service.serviceHierarchy[serviceModelId])));
FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS ='FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS',
FLAG_2004_INSTANTIATION_STATUS_FILTER ='FLAG_2004_INSTANTIATION_STATUS_FILTER',
FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE = 'FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE',
- FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER ='FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER',
- FLAG_2004_INSTANTIATION_TEMPLATES_POPUP = 'FLAG_2004_INSTANTIATION_TEMPLATES_POPUP'
+ FLAG_2006_VFM_SDNC_PRELOAD_FILES = 'FLAG_2006_VFM_SDNC_PRELOAD_FILES',
+ FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO = 'FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO',
+ FLAG_2004_INSTANTIATION_TEMPLATES_POPUP = 'FLAG_2004_INSTANTIATION_TEMPLATES_POPUP',
+ FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY= 'FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY',
+ FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF = 'FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF',
}
@Injectable()
import {GenericFormPopupService} from "./components/genericFormPopup/generic-form-popup.service";
import {FormGeneralErrorsService} from "./components/formGeneralErrors/formGeneralErrors.service";
import {VnfPopupService} from "./components/genericFormPopup/genericFormServices/vnf/vnf.popup.service";
-import {SdcUiComponentsModule, SdcUiServices} from "onap-ui-angular";
import {SafePipe} from "./pipes/safe/safe.pipe";
import {ViewEditResolver} from "./resolvers/viewEdit/viewEdit.resolver";
import {FlagsResolve} from "./resolvers/flag/flag.resolver";
import {RecreateResolver} from "./resolvers/recreate/recreate.resolver";
import {InstantiationTemplatesService} from "./services/templateService/instantiationTemplates.service";
import {SharedControllersService} from "./components/genericForm/formControlsServices/sharedControlles/shared.controllers.service";
+import {DuplicateVnfComponent} from "../drawingBoard/service-planning/duplicate/duplicate-vnf.component";
+import {ModalService} from "./components/customModal/services/modal.service";
+import {CreateDynamicComponentService} from "./components/customModal/services/create-dynamic-component.service";
+import {ModalComponent} from "./components/customModal/modal.component";
+import {ModalCloseButtonComponent} from './components/customModal/components/modalCloseButton/modal-close-button.component';
+import {CustomButtonComponent} from "./components/customButton/custom-button.component";
+import {CustomModalButtonComponent} from "./components/customModal/components/modalButton/modal-button.component";
+import {CustomRippleClickAnimationDirective} from "./components/customModal/directives/ripple-click.animation.directive";
+import {LoaderComponent} from "./components/customLoader/custom-loader.component";
+import {LoaderService} from "./components/customLoader/custom-loader.service";
+import {SvgIconComponent} from "./components/customIcon/custom-icon.component";
+import {TooltipTemplateComponent} from "./components/customTooltip/custom-tooltip.component";
+import {TooltipDirective} from "./components/customTooltip/tooltip.directive";
+import {SdcUiComponentsModule} from "onap-ui-angular";
+import {UploadFilesLinkComponent} from "./components/genericForm/genericFormSharedComponent/uploadFiles/upload-files-link.component";
+import { FileUploadModule } from 'ng2-file-upload';
+import {MessageModal} from "./components/messageModal/message-modal.service";
+
@NgModule({
FeatureFlagModule.forRoot(),
FormsModule,
ReactiveFormsModule,
- TooltipModule,
SdcUiComponentsModule,
+ TooltipModule,
AngularMultiSelectModule,
BootstrapModalModule,
DataTableModule,
- ModalModule.forRoot()
+ ModalModule.forRoot(),
+ FileUploadModule
],
declarations: [
PopoverComponent,
NumberFormControlComponent,
InputPreventionPatternDirective,
ClickOutsideDirective,
+ TooltipDirective,
+ CustomRippleClickAnimationDirective,
FormGeneralErrorsComponent,
SpinnerComponent,
NoContentMessageAndIconComponent,
ErrorMsgComponent,
DynamicInputsComponent,
DynamicInputLabelPipe,
- InstantiationTemplatesModalComponent
+ InstantiationTemplatesModalComponent,
+ ModalComponent,
+ ModalCloseButtonComponent,
+ CustomButtonComponent,
+ CustomModalButtonComponent,
+ LoaderComponent,
+ SvgIconComponent,
+ TooltipTemplateComponent,
+ UploadFilesLinkComponent
],
exports: [
PopoverComponent,
FormControlErrorComponent,
DropdownFormControlComponent,
InputPreventionPatternDirective,
+ CustomRippleClickAnimationDirective,
ClickOutsideDirective,
+ TooltipDirective,
FormGeneralErrorsComponent,
SpinnerComponent,
NoContentMessageAndIconComponent,
ErrorMsgComponent,
SvgComponent,
DynamicInputsComponent,
- DynamicInputLabelPipe
+ DynamicInputLabelPipe,
+ ModalComponent,
+ ModalCloseButtonComponent,
+ CustomButtonComponent,
+ CustomModalButtonComponent,
+ LoaderComponent,
+ SvgIconComponent,
+ TooltipTemplateComponent,
+ UploadFilesLinkComponent
],
entryComponents : [
GenericFormPopupComponent,
SearchElementsModalComponent,
- InstantiationTemplatesModalComponent
+ InstantiationTemplatesModalComponent,
+ DuplicateVnfComponent,
+ ModalComponent
],
providers: [
ServiceInfoService,
MessageBoxService,
- SdcUiServices.ModalService,
- SdcUiServices.LoaderService,
+ CreateDynamicComponentService,
+ ModalService,
+ LoaderService,
HttpInterceptorService,
IframeService,
DefaultDataGeneratorService,
SearchFilterPipe,
ModelInformationService,
MultiselectFormControlService,
- InstantiationTemplatesModalService
+ InstantiationTemplatesModalService,
+ LoaderService,
+ MessageModal
]
})
export class SharedModule {
public static SERVICE_MODEL_ID = 'serviceModelId';
public static SERVICES_RETRY_TOPOLOGY = '../../asyncInstantiation/bulkForRetry';
public static INSTANTIATION_TEMPLATE_TOPOLOGY = '../../instantiationTemplates/templateTopology';
+ public static PRE_LOAD = '../../preload';
public static CONFIGURATION_PATH = '../../get_property/{name}/defaultvalue';
public static SERVICES_JOB_AUDIT_PATH = '/auditStatus';
public static SERVICES_PROBE_PATH = "../../probe";
constructor(private store: NgRedux<AppState>, private _formAsyncService: FormAsyncService) { }
- @ViewChild('form') form: NgForm;
+ @ViewChild('form', {static: false}) form: NgForm;
@Input()
set params(params: any) {
if (params) {
@select(['service', 'networkFunctions'])
readonly networkFunctions: Observable<any>;
- @ViewChild('form') form: NgForm;
+ @ViewChild('form', {static: false}) form: NgForm;
constructor(store: NgRedux<AppState>) {
this.localStore = store;
readonly userIdObs: Observable<any>;
- @ViewChild(NetworkSelectorComponent)
- public networkSelectorComponent: NetworkSelectorComponent;
- @ViewChild(Formasync)
- public formAsync: Formasync;
-
+ @ViewChild(NetworkSelectorComponent, {static: false}) networkSelectorComponent: NetworkSelectorComponent;
+ @ViewChild(Formasync, {static: false}) formAsync: Formasync;
deploySubInterface() {
isNextButtonDisabled() {
switch (this.currentStep) {
case WizardSteps.one:
- return !this.formAsync.form.valid;
+ return this.formAsync ? !this.formAsync.form.valid : false;
case WizardSteps.two:
- return !this.networkSelectorComponent.form.valid;
+ return this.networkSelectorComponent ? !this.networkSelectorComponent.form.valid : false;
}
}
display: none !important;
}
-
+sdc-modal {
+ z-index: 10000 !important;
+}